Menu
CoddyTech

Duck-Typisierung

Teil des Abschnitts Objektorientierte Programmierung der GDScript-Journey von Coddy. Lektion 22 von 65.

Duck-Typing interessiert sich dafür, was ein Objekt tun kann, nicht zu welcher Klasse es gehört. Wenn es die Methode hat, die du aufrufst, funktioniert der Aufruf. Der Name stammt von der Redewendung „Wenn es wie eine Ente schwimmt und wie eine Ente quakt, ist es eine Ente“.

Diese beiden Klassen haben kein gemeinsames übergeordnetes Element, aber beide verfügen über swim() und quack():

# duck.gd
class_name Duck
extends RefCounted

func swim() -> String:
	return "Duck swimming"

func quack() -> String:
	return "Quack!"
# robot.gd
class_name Robot
extends RefCounted

func swim() -> String:
	return "Robot swimming with propellers"

func quack() -> String:
	return "Robot sound: BEEP BEEP!"

Ein Parameter ohne Typ akzeptiert jedes Objekt. Die Funktion ruft die Methoden auf, und jedes Objekt führt seine eigenen aus:

func make_it_swim_and_quack(thing) -> void:
	print(thing.swim())
	print(thing.quack())
make_it_swim_and_quack(Duck.new())
make_it_swim_and_quack(Robot.new())
Duck swimming
Quack!
Robot swimming with propellers
Robot sound: BEEP BEEP!

Für das Überschreiben ist eine gemeinsame Elternklasse erforderlich; Duck-Typing nicht. Bei der Typangabe des Parameters als thing: Duck wäre das Übergeben eines Robot ein Parse-Fehler.

Wenn einem Objekt die Methode fehlt, bricht der Aufruf die Funktion mit einem Fehler ab, z. B. Invalid call. Nonexistent function 'quack'. Frage zuerst mit has_method() nach; dabei wird der Methodenname als String übergeben:

var things := [Duck.new(), Rock.new()]
for thing in things:
	if thing.has_method("quack"):
		print(thing.quack())
	else:
		print("This one cannot quack")
Quack!
This one cannot quack

Der Preis: Mit Typen erkennt Godot einen falschen Methodennamen, bevor das Programm ausgeführt wird; bei Duck-Typing findest du es erst heraus, wenn die Zeile ausgeführt wird. Verwende es für Objekte nicht verwandter Klassen, die einige Methoden gemeinsam haben.

challenge icon

Aufgabe

Einfach

Eine Explosion beschädigt alles in der Nähe, das Schaden nehmen kann. Die Objekte haben keine gemeinsame Elternklasse. player.gd und rock.gd sind fertig: Ein Player hat take_damage(amount) und status(), ein Rock hat nur status().

  • Gib in crate.gd Crate eine Variable broken, die mit false beginnt, eine Methode take_damage(amount), die die Kiste bei einem Betrag von 10 oder mehr zerbricht, und eine Methode status(), die Crate: broken oder Crate: intact zurückgibt.
  • Schreibe in explosion.gd die statische Methode hit_all(things, amount). Sie ruft bei jedem Objekt im Array, das diese Methode hat, take_damage(amount) auf und gibt zurück, wie viele Objekte sie getroffen hat.

Der bereitgestellte Code liest eine Zeile mit Objektnamen (player, crate oder rock), dann die Anzahl der folgenden Explosionen und den Schaden jeder Explosion. Er gibt aus, wie viele Objekte jede Explosion getroffen hat, und danach den Status jedes Objekts. Für player crate rock und Explosionen mit 5 und 20 gibt er Folgendes aus:

Explosion 1 hit 2 objects
Explosion 2 hit 2 objects
Player: 75 HP
Crate: broken
Rock: solid

Dein Code gehört in crate.gd und explosion.gd. main.gd enthält den bereitgestellten Ein-/Ausgabecode und darf nicht bearbeitet werden.

Probier es selbst

extends Node

func _ready():
	# Vorgegebener Eingabe-/Ausgabecode: Lass ihn unverändert
	var things := []
	for word in OS.read_string_from_stdin().split(" "):
		if word == "player":
			things.append(Player.new())
		elif word == "crate":
			things.append(Crate.new())
		else:
			things.append(Rock.new())
	var count := int(OS.read_string_from_stdin())
	for i in count:
		var hits := Explosion.hit_all(things, int(OS.read_string_from_stdin()))
		print("Explosion %d hit %d objects" % [i + 1, hits])
	for thing in things:
		print(thing.status())
quiz iconTeste dich selbst

Diese Lektion enthält ein kurzes Quiz. Starte die Lektion, um es zu beantworten und deinen Fortschritt zu speichern.

Alle Lektionen in Objektorientierte Programmierung

Übe selbstständig: Online-GDScript-Compiler