Menu
CoddyTech

再谈方法重写

本课属于 Coddy GDScript 学习旅程的“面向对象编程”单元。第 21 课,共 65 课。

多态的意思是“多种形式”:一次方法调用会根据接收调用的对象所属的类执行不同的操作。重写让这一切成为可能。

# animal.gd
class_name Animal
extends RefCounted

func speak() -> String:
	return "..."
# dog.gd
class_name Dog
extends Animal

func speak() -> String:
	return "Woof!"
# cat.gd
class_name Cat
extends Animal

func speak() -> String:
	return "Meow!"

Array[Animal] 可以保存它们所有对象。循环调用 speak(),而无需知道每个元素属于哪个类,每个对象都会用自己的版本作出响应:

var animals: Array[Animal] = [Dog.new(), Cat.new(), Animal.new()]
for animal in animals:
	print(animal.speak())
Woof!
Meow!
...

带有 Animal 参数的函数也是如此。它可以接受所有子类,包括你以后添加的类,无需做任何修改:

func make_it_speak(animal: Animal) -> void:
	print("It says ", animal.speak())
make_it_speak(Cat.new())
It says Meow!

把它和逐个检查类进行比较。每增加一个新类,if animal is Dog: 分支链就必须变长。使用重写时,每个类都带有自己的行为,而调用它的代码保持不变。

challenge icon

挑战

简单

车库通过一个 Array[Vehicle] 处理所有车辆。在 vehicle.gd 中,wheels() 返回 0,sound() 返回 ...。

  • 在 Vehicle 中编写 describe()。它会调用 wheels() 和 sound(),并返回 BRAND: N wheels, SOUND。
  • Car 重写 wheels(),使其返回 4,并重写 sound(),使其返回 Vroom。
  • Motorcycle 重写这两个方法,分别使其返回 2 和 Brrm。
  • Truck 已经存储了 trailers 的数量。它重写 wheels(),使其返回 6 加上每个拖车 4 个轮子,并重写 sound(),使其返回 Honk。

子类不会重写 describe()。提供的代码会读取后续车辆的数量,然后每辆车读取一行:car BRAND、motorcycle BRAND、truck BRAND TRAILERS 或 vehicle BRAND。代码会打印每辆车的 describe() 结果,以及 wheels() 的总和。输入 car Toyota 和 truck Volvo 2 时,会打印:

Toyota: 4 wheels, Vroom
Volvo: 14 wheels, Honk
Total wheels: 18

你的代码要写在 vehicle.gd、car.gd、motorcycle.gd 和 truck.gd 中。main.gd 中包含提供的输入和输出代码,不能编辑。

亲手试试

extends Node

func _ready():
	# 提供的输入输出代码:保持原样
	var count := int(OS.read_string_from_stdin())
	var vehicles: Array[Vehicle] = []
	for i in count:
		var p := OS.read_string_from_stdin().split(" ")
		if p[0] == "car":
			vehicles.append(Car.new(p[1]))
		elif p[0] == "motorcycle":
			vehicles.append(Motorcycle.new(p[1]))
		elif p[0] == "truck":
			vehicles.append(Truck.new(p[1], int(p[2])))
		else:
			vehicles.append(Vehicle.new(p[1]))
	var total := 0
	for v in vehicles:
		print(v.describe())
		total += v.wheels()
	print("Total wheels: %d" % total)
quiz icon自我测试

这节课包含一个小测验。开始学习即可作答,并记录你的进度。

面向对象编程中的所有课

自己练习: GDScript 在线编译器