Overriding a function means replacing a function already defined in a parent class. We say that we replace the function implementation.
In GDScript, we can override a function by defining a function with the same name and parameters as the parent class. When we define a function with the same name and parameters, the function in the parent class is replaced by the function in the child class.
Here's an example with a parent Item
class and a child Potion
class. The Item
class has a generic use()
function that takes a game actor as an input and does nothing. The Potion
class extends the Item
class and overrides the use()
function to heal the target by 10
health points.
class_name Item
func use(target: Actor) -> void:
pass
class_name Potion extends Item
func use(target: Actor) -> void:
target.heal(10)
When overriding a function, the override needs to remain compatible with the original function definition. Precisely, in GDScript:
- Add function parameters compared to the parent.
- Remove parameters compared to the parent.
- Change the type of parameters in a child's function to a more specialized compatible type.
- Change the type of parameters in a child's function to a more generic type
- Change the type of return in a child's function to a more specialized type
NOTE:These rules are not true for the _init()
method, see below
To illustrate the last two points:
class GenericParameter:
pass
class SpecializedParameter extends GenericParameter:
pass
class Generic:
func example(parameter: SpecializedParameter) -> void:
pass
class Specialized extends Generic:
func example(parameter: GenericParameter) -> void:
pass
In this example, Specialized
can make the example()
function take a more generic type, but not a stricter one.
However, return types can do the opposite:
class GenericParameter:
pass
class SpecializedParameter extends GenericParameter:
pass
class Generic:
func example() -> GenericParameter:
return SpecializedParameter.new()
class Specialized extends Generic:
func example() -> SpecializedParameter:
return GenericParameter.new()
When we define functions like _process()
, we override the _process()
function from the Godot engine. The code in our script gets called instead of the code in the engine. Well, in the case of the _process()
function, the engine version does nothing. So, overriding it makes the function do something.
Here's an example of overriding the _process()
function in an Actor
class to move the actor around the screen. We'll see below how to extend this class and extend the _process()
function instead of replacing it.
class_name Actor
var speed := 500.0
func _process(delta: float) -> void:
var direction := Input.get_vector("move_left", "move_right", "move_up", "move_down")
position += direction * speed * delta
When we call the use()
function on a Potion
object, the use()
function in the Potion
class gets called instead of the corresponding function in the Item
class. The override replaces the parent function.
Similarly, when we extend a script and override the _process()
function, the code in the child script replaces the code in the parent script.
To extend a function instead of replacing it, we can explicitly tell GDScript to call the parent version using the super
keyword. The super
keyword is a common way to refer to the parent class. It's present in many programming languages.
Here's a character that extends the Actor
class example above and rotates based on the movement direction:
class_name Character extends Actor
func _process(delta: float) -> void:
super._process(delta)
if direction.length() > 0.0:
rotation = direction.angle()
Let's break down the code:
- We call
super._process(delta)
to call the _process()
function in the parent class. This runs the code that calculates the direction and moves the character.
- We then add our own code to rotate the character based on the direction.
The _init() has some special rules; namely, you can change the arguments completely, as long as you call super()
with the correct parent arguments.
For example, the below is valid:
class Generic:
var name := "Generic"
func _init(initial_name: String) -> void:
name = initial_name
class Specialized extends Generic:
var age := 0
func _init(initial_age: int) -> void:
super("Specialized")
age = initial_age
See Also
Related terms in the Glossary