Menu
CoddyTech

Inheritance Chains

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

A child class can itself be a parent. Each extends adds one level to an inheritance chain:

# vehicle.gd
class_name Vehicle
extends RefCounted

var wheels: int

func _init(w: int) -> void:
	wheels = w

func describe() -> String:
	return "%d wheels" % wheels
# car.gd
class_name Car
extends Vehicle

func _init() -> void:
	super(4)

func describe() -> String:
	return "Car with " + super()
# race_car.gd
class_name RaceCar
extends Car

var top_speed: int

func _init(speed: int) -> void:
	super()
	top_speed = speed

func describe() -> String:
	return super() + ", top speed %d" % top_speed

RaceCar has everything from Car and from Vehicle. Each super() goes up one level, so one call runs all three versions of describe():

print(RaceCar.new(300).describe())
Car with 4 wheels, top speed 300

When you call a method or read a variable, Godot looks in the object's own class first, then in its parent, then in the parent's parent, and uses the first one it finds. RaceCar.new(300).wheels is found in Vehicle, two levels up.

Every class has exactly one parent. extends takes a single class, and listing two is a parse error:

class_name FlyingCar
extends Car, Plane
Parse Error: Expected end of statement after superclass, found "," instead.

GDScript has no multiple inheritance. When a class needs the features of two classes, put them on one chain, or give it an object of the other class to work with (a later chapter covers this).

challenge icon

Challenge

Easy

character.gd holds the finished Character class: a name, hp, describe() returning NAME (HP HP) and attack() returning 1. Build two more levels on it:

  • Warrior extends Character and adds strength. Its constructor passes the name and hp to super(). describe() adds , strength S to the parent's text, and attack() returns the strength.
  • Knight extends Warrior and adds armor. Its constructor passes the name, hp and strength to super(). describe() adds , armor A to the text of Warrior, and attack() returns the attack of Warrior plus 5.

The supplied code reads how many characters follow, then one line per character: character NAME HP, warrior NAME HP STRENGTH or knight NAME HP STRENGTH ARMOR. It prints describe() and the attack. For knight Arthur 120 15 8 it prints:

Arthur (120 HP), strength 15, armor 8
Attack: 20

Your code goes in warrior.gd and knight.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 count := int(OS.read_string_from_stdin())
	for i in count:
		var p := OS.read_string_from_stdin().split(" ")
		var c: Character
		if p[0] == "knight":
			c = Knight.new(p[1], int(p[2]), int(p[3]), int(p[4]))
		elif p[0] == "warrior":
			c = Warrior.new(p[1], int(p[2]), int(p[3]))
		else:
			c = Character.new(p[1], int(p[2]))
		print(c.describe())
		print("Attack: %d" % c.attack())
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