メソッドのオーバーライド
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()を呼び出します。そして、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()で代入します。
チャレンジ
簡単shape.gdには完成したShapeクラスがあります。color、0.0を返すarea()、およびdescribe()です。CircleとSquareはこれを継承しており、コンストラクターもすでに用意されています。それぞれのクラスで2つのメソッドをオーバーライドしてください。
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。
用意されているコードは、続く図形の数を読み取ってから、図形ごとに1行を読み取ります。形式はshape COLOR、circle COLOR RADIUS、またはsquare COLOR SIDEです。describe()と、小数点以下2桁の面積を出力します。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())
このレッスンには短いクイズがあります。レッスンを始めて解答し、進捗を記録しましょう。
オブジェクト指向プログラミングのすべてのレッスン
自分で練習してみよう: GDScriptオンラインコンパイラ