mandmeier
mandmeier

Reputation: 409

Godot: How to disable/overwrite inherited function?

I am trying to come up with an efficient way to organize clickable menus for the objects in my game. I made a Menu class, from which all possible menus inherit:

class_name Menu extends Control

#contains functions (for buttons) that all menus have in common

func open_menu():
  pass

func close_menu():
  pass

To make a menu specific to buildings, I inherit all functionalities from the Menu class:

class_name BuildingMenu extends Menu

# contains functions specific to all buildings

func upgrade_building():
  pass

func delete_building():
  pass

# ... many more ...

Now here's the problem: My HQ is literally just another building with a few extras and the main difference that it can't be deleted, so I'm thinking of inheriting from BuildingMenu. Is there a way to disable the inherited delete_building() function in the HQMenu script?

class_name HQMenu extends BuildingMenu


func delete_building():
  # overwriting inherited function like this does not work...


# ... some HQ specific stuff here ...


I could just inherit from Menu and then copy paste everything from BuildingMenu except the delete_building() method, but this seems somewhat clumsy because now I have to edit two files if I want to change/add any building functions.

What is the correct way to do this?

SOLUTION:

Thanks to the suggestion by Thearot I've decided to move the delete_building() function into a new class from which all the regular (non HQ) buildings inherit:

enter image description here

Upvotes: 0

Views: 2154

Answers (1)

Theraot
Theraot

Reputation: 40315

Now here's the problem: My HQ is literally just another building with a few extras and the main difference that it can't be deleted, so I'm thinking of inheriting from BuildingMenu. Is there a way to disable the inherited delete_building() function in the HQMenu script?

This sounds like a violation of Liskov Substitution Principle. From a purely object oriented point of view, it would be preferible to make another class for a subset of buildings with what they have in common, than to have one building inherit from another if it has to disable some methods.

If your base class for all buildings implies that some buildings have to disable some methods, then it does not really have the methods common for all building, it has some extra ones.

To be clear, here I'm suggesting to add another extra intermediary class, and that way you don't have to delete nor duplicate methods.


If that is not an option for you… Congratulations! you have made a mess system complex enough that some kind of component based system begins to make sense. But don't jump the line, don't fret, it is OK.

If I understand correctly you have some contextual menus that show different options depending on what is selected or what you click on, right?

That means that the options are variable. Thus, use a variable. Add an Array field that has the names of the methods that should be linked to the menu. Then have the menu system discover the options by reading that Array, and connecting to functions with the names specified there.

And how you do add or remove options? You add them or remove them form the Array. Simple. You can populate the Array in _init.

To be clear, you can check if an object has a method with has_method. You call a method by name with call, or - of course - you could connect signals to them with connect (if prefer to populate an static menu for the object instead of having a dynamic one). Yes, I'm suggesting late binding.

Upvotes: 1

Related Questions