Menu
CoddyTech

方法重写

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

子类通过定义一个同名方法来重写方法。子类的对象随后会运行子类版本,而没有重写的方法仍会原样继承。

# animal.gd
class_name Animal
extends RefCounted

var animal_name: String

func _init(n: String) -> void:
	animal_name = n

func make_sound() -> void:
	print("Some generic animal sound")

func info() -> void:
	print("I am ", animal_name)
# dog.gd
class_name Dog
extends Animal

func make_sound() -> void:
	print("Woof! Woof!")
var animal := Animal.new("Generic")
var dog := Dog.new("Buddy")
animal.make_sound()
dog.make_sound()
dog.info()
Some generic animal sound
Woof! Woof!
I am Buddy

重写的方法必须保留父类的签名:参数和返回类型都要相同。如果不一致,程序就无法启动:

# animal.gd
func speak(times: int) -> String:
	return "...".repeat(times)
# dog.gd
func speak() -> String:
	return "Woof"
Parse Error: The function signature doesn't match the parent. Parent signature is "speak(int) -> String".

即使调用来自父类的方法,也会运行子类的版本。这里,introduce() 只存在于 Animal 中,它会调用 sound(),而 Cat 重写了这个方法:

# animal.gd
func sound() -> String:
	return "..."

func introduce() -> String:
	return animal_name + " says " + sound()
# cat.gd
func sound() -> String:
	return "Meow"
print(Cat.new("Tom").introduce())
Tom says Meow

变量不能被覆盖:在 Dog 中再次声明 var animal_name 会导致解析错误(The member "animal_name" already exists in parent class Animal)。要给子类设置不同的初始值,请在子类的 _init() 中赋值。

challenge icon

挑战

简单

shape.gd 中包含已完成的 Shape 类:一个 color、返回 0.0 的 area(),以及 describe()。Circle 和 Square 继承了它,并且已经有了构造函数。请分别重写这两个方法:

  • Circle:area() 返回 PI * radius * radius,describe() 返回 This is a COLOR circle with radius R。
  • Square:area() 返回 side * side,describe() 返回 This is a COLOR square with side S。

保留父类的方法签名:func area() -> float 和 func describe() -> String。

提供的代码会读取后续图形的数量,然后每个图形读取一行:shape COLOR、circle COLOR RADIUS 或 square COLOR SIDE。它会输出 describe() 的结果和保留两位小数的面积。对于 circle red 5 和 shape green,输出如下:

This is a red circle with radius 5
Area: 78.54
This is a green shape
Area: 0.00

请将代码写入 circle.gd 和 square.gd。main.gd 中包含提供的输入/输出代码,不能编辑。

亲手试试

extends Node

func _ready():
	# 提供的输入/输出代码:保持原样。
	var count := int(OS.read_string_from_stdin())
	for i in count:
		var parts := OS.read_string_from_stdin().split(" ")
		var shape: Shape
		if parts[0] == "circle":
			shape = Circle.new(parts[1], int(parts[2]))
		elif parts[0] == "square":
			shape = Square.new(parts[1], int(parts[2]))
		else:
			shape = Shape.new(parts[1])
		print(shape.describe())
		print("Area: %.2f" % shape.area())
quiz icon自我测试

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

面向对象编程中的所有课

自己练习: GDScript 在线编译器