継承の連鎖
CoddyのGDScriptジャーニー「オブジェクト指向プログラミング」セクションの一部。レッスン 18/65。
子クラス自体が親クラスになることもできます。各extendsは継承チェーンに1つのレベルを追加します。
# 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_speedRaceCarはCarとVehicleの両方からすべてを引き継ぎます。各super()は1段階上に進むため、1回の呼び出しでdescribe()の3つすべてのバージョンが実行されます:
print(RaceCar.new(300).describe())Car with 4 wheels, top speed 300メソッドを呼び出したり変数を読み取ったりすると、Godotはまずオブジェクト自身のクラスを探し、次にその親、さらに親の親を探して、最初に見つかったものを使います。RaceCar.new(300).wheelsは、2階層上のVehicleで見つかります。
すべてのクラスには親クラスが1つだけあります。extendsは1つのクラスを指定し、2つ指定すると構文解析エラーになります:
class_name FlyingCar
extends Car, PlaneParse Error: Expected end of statement after superclass, found "," instead.GDScriptは多重継承に対応していません。あるクラスが2つのクラスの機能を必要とする場合、それらを1つの継承チェーンにまとめるか、もう一方のクラスのオブジェクトを渡して利用します(この点については後の章で説明します)。
チャレンジ
簡単character.gdには完成済みのCharacterクラスがあります。名前、hp、NAME (HP HP)を返すdescribe()、そして1を返すattack()です。これをもとに、さらに2つの階層を作りましょう。
WarriorはCharacterを継承し、strengthを追加します。コンストラクターでは、名前とhpをsuper()に渡します。describe()は親クラスのテキストに, strength Sを追加し、attack()はstrengthを返します。KnightはWarriorを継承し、armorを追加します。コンストラクターでは、名前、hp、strengthをsuper()に渡します。describe()はWarriorのテキストに, armor Aを追加し、attack()はWarriorのattackに5を加えた値を返します。
提供されたコードは、続くキャラクターの数を読み取り、キャラクターごとに1行を読み込みます。形式はcharacter NAME HP、warrior NAME HP STRENGTH、またはknight NAME HP STRENGTH ARMORです。describe()の結果とattackを出力します。knight Arthur 120 15 8の場合、次のように出力します。
Arthur (120 HP), strength 15, armor 8
Attack: 20コードはwarrior.gdとknight.gdに記述します。main.gdには提供された入出力コードがあり、編集できません。
自分で試してみよう
extends Node
func _ready():
# 用意された入出力コード: そのままにしてください
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())
このレッスンには短いクイズがあります。レッスンを始めて解答し、進捗を記録しましょう。
オブジェクト指向プログラミングのすべてのレッスン
自分で練習してみよう: GDScriptオンラインコンパイラ