Menu
CoddyTech

Virtual Methods Introduction

Part of the Object Oriented Programming section of Coddy's GDScript journey. Lesson 31 of 65.

Python has magic methods such as __init__ and __str__, which the language calls for you. Godot's version is the virtual method: a method with a fixed name, starting with an underscore, that you define in your class and Godot calls at the right moment. You have used two already:

  • _init() runs when new() creates the object, with the arguments given to new().
  • _ready() runs when a node enters the scene tree, which is where main.gd starts.

Others are _to_string(), called when an object is printed, the iterator methods that let a for loop walk through an object (both in the next lessons), and _notification(), which receives events from the engine. One of them, NOTIFICATION_PREDELETE, arrives right before the object is deleted:

# torch.gd
class_name Torch
extends RefCounted

var label: String

func _init(new_label: String = "Torch") -> void:
	label = new_label
	print(label, " lit")

func _notification(what: int) -> void:
	if what == NOTIFICATION_PREDELETE:
		print(label, " burned out")
# main.gd
var torch := Torch.new("Hall torch") # Hall torch lit
torch = null # Hall torch burned out

A RefCounted object is deleted as soon as no variable refers to it any more, so torch = null sends the notification at once. The default value in _init() makes the argument of new() optional: Torch.new() creates a torch called Torch.

Python also uses magic methods for operators, such as __add__ for + and __eq__ for ==. GDScript has no operator overloading: potion_a + potion_b is an error. Write a method instead:

# potion.gd
class_name Potion
extends RefCounted

var power: int

func _init(start_power: int) -> void:
	power = start_power

func combined(other: Potion) -> Potion:
	return Potion.new(power + other.power)

potion_a.combined(potion_b) returns a new potion and leaves both originals unchanged. == between two objects checks whether both sides are the same object, not whether their values match: Potion.new(5) == Potion.new(5) is false. Write a method such as equals(other) when you need to compare values.

challenge icon

Challenge

Easy

Write the Counter class in counter.gd:

  • _init(start = 0, step_size = 1) stores the start in value and the step size in step. The defaults are already in the signature, so Counter.new(), Counter.new(5) and Counter.new(5, 2) all work.
  • tick() adds step to value.
  • plus(other) replaces the + operator, which GDScript does not let you define: it returns a new Counter whose value is the sum of both values and whose step is this counter's step. Neither counter changes.
  • equals(other) returns true when both counters have the same value.

The supplied code reads two lines that create the counters a and b (an empty line, START or START STEP), then one line with how many times to tick a and b. It prints both counters, their sum, whether their values are equal and whether a == b. For the lines 5, 2 3 and 3 1 it prints:

a: 8 (step 1)
b: 5 (step 3)
a plus b: 13 (step 1)
same value: false
same object: false

Your code goes in counter.gd. main.gd holds the supplied input/output code and cannot be edited.

Try it yourself

extends Node

func _ready():
	# Supplied input/output code: keep it as it is
	var a := make_counter(OS.read_string_from_stdin())
	var b := make_counter(OS.read_string_from_stdin())
	var ticks := OS.read_string_from_stdin().split(" ")
	for i in int(ticks[0]):
		a.tick()
	for i in int(ticks[1]):
		b.tick()
	print("a: %d (step %d)" % [a.value, a.step])
	print("b: %d (step %d)" % [b.value, b.step])
	var total := a.plus(b)
	print("a plus b: %d (step %d)" % [total.value, total.step])
	print("same value: %s" % a.equals(b))
	print("same object: %s" % (a == b))

func make_counter(line: String) -> Counter:
	var parts := line.split(" ", false)
	if parts.is_empty():
		return Counter.new()
	if parts.size() == 1:
		return Counter.new(int(parts[0]))
	return Counter.new(int(parts[0]), int(parts[1]))
quiz iconTest yourself

This lesson includes a short quiz. Start the lesson to answer it and track your progress.

All lessons in Object Oriented Programming

Practice on your own: Online GDScript compiler