See all glossary terms

Overriding a function

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)

Overriding rules

When overriding a function, the override needs to remain compatible with the original function definition. Precisely, in GDScript:
You can't:
  1. Add function parameters compared to the parent.
  2. Remove parameters compared to the parent.
  3. Change the type of parameters in a child's function to a more specialized compatible type.
You can:
  1. Change the type of parameters in a child's function to a more generic type
  2. 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()

Overriding built-in functions

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

The override replaces the parent function

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:
  1. 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.
  2. We then add our own code to rotate the character based on the direction.

The special _init() method

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