Search code examples
inheritancecode-organizationgdscript

How to organize multiple levels of class inheritance?


Note about the language: it has classes that can inherit one another. If a descendant class has a function with the same name as a function in an ancestor class, the function in the ancestor class will not run at all for instances of the descendant.

Problem: I want to know what's the best way to create functions that expand on the behaviours of ancestor classes without overriding any of them.

Pseudocode of what I'm doing right now:

class_name Animal

func _doSomething():
  #do something common to "Animal"
  _doSomething_descendantOfAnimal()

func _doSomething_descendantOfAnimal():
  #no behaviour here, since it will be overridden by descendants

Code for another class extending "Animal"

class_name Feline
extends Animal

func _doSomething_descendantOfAnimal():
  #behaviour common to "Feline"
  _doSomething_descendantOfFeline()
 
func _doSomething_descendantOfFeline():
  #no behaviour here

Code for another class extending "Feline"

class_name HouseCat
extends Feline

func _doSomething_descendantOfFeline():
  #behaviour specific to "HouseCat"

This organization means that when I call _doSomething() on a HouseCat instance, the behaviours common to Animal and Feline will run in addition to any specific behaviour of HouseCat itself. Nevertheless, I feel like there is a cleaner, more efficient way to do things. One that doesn't require me to add a blank function (like _doSomething_descendantOfFeline()) to each class that can possibly be extended by another, for example.


Solution

  • What you would usually do is the following: have the function override the function of parent class, with code that calls the function of parent class. GDScript syntax for it is .. For GDScript 2.0 in Godot 4, it is super..

    Example from the official documentation for Godot 4.1:

    func some_func(x):
        super(x) # Calls the same function on the parent class.
    

    See GDScript basics: class inheritance (latest stable version).

    Godot 3.6 example:

    func some_func(x):
        .some_func(x) # Calls the same function on the parent class.
    

    See GDScript basics: class inheritance (Godot 3.6).