GDScriptの継承とポリモーフィズムの応用

Gobot

GDScriptにおける継承とポリモーフィズム:牛肉・豚肉・鶏肉・ジビエ情報の活用

GDScriptは、Godot Engineで利用されるオブジェクト指向プログラミング言語です。その強力な機能の一つに、継承とポリモーフィズムがあります。これらの概念は、コードの再利用性、拡張性、そして柔軟性を劇的に向上させます。本稿では、これらを「牛肉」「豚肉」「鶏肉」「ジビエ」という具体的な情報群を例に、その応用について解説します。

継承:共通の基盤を築く

継承は、既存のクラス(親クラス)のプロパティやメソッドを新しいクラス(子クラス)が引き継ぐ仕組みです。これにより、共通の機能を再定義する手間を省き、コードの重複を避けることができます。

基底クラス「肉」の定義

まず、全ての肉製品に共通する基本的な情報を格納する基底クラス `Meat` を定義します。このクラスは、肉の種類、価格、栄養価などの共通属性を持つと想定できます。

class Meat:
var type: String = “Unknown”
var price_per_kg: float = 0.0
var calories_per_100g: float = 0.0

func get_description() -> String:
return “Type: %s, Price: %.2f/kg, Calories: %.2f/100g” % [type, price_per_kg, calories_per_100g]

牛肉クラス:`Meat` を継承

次に、`Meat` クラスを継承して `Beef` クラスを作成します。ここでは、牛肉特有の情報(例:部位、霜降り度)を追加できます。

class Beef extends Meat:
var cut: String = “Unknown Cut”
var marbling_score: int = 0

func _init(p_cut: String, p_price: float, p_calories: float, p_marbling: int):
type = “Beef”
cut = p_cut
price_per_kg = p_price
calories_per_100g = p_calories
marbling_score = p_marbling

func get_description() -> String:
var base_desc = super.get_description() # 親クラスのメソッドを呼び出す
return “%s, Cut: %s, Marbling: %d” % [base_desc, cut, marbling_score]

豚肉クラス:`Meat` を継承

同様に、`Pork` クラスも `Meat` を継承し、豚肉特有の情報を格納します。

class Pork extends Meat:
var breed: String = “Unknown Breed”

func _init(p_breed: String, p_price: float, p_calories: float):
type = “Pork”
breed = p_breed
price_per_kg = p_price
calories_per_100g = p_calories

func get_description() -> String:
var base_desc = super.get_description()
return “%s, Breed: %s” % [base_desc, breed]

鶏肉クラス:`Meat` を継承

さらに、`Chicken` クラスも `Meat` を継承します。鶏肉の場合、部位(むね、ももなど)や品種が重要になる場合があります。

class Chicken extends Meat:
var part: String = “Unknown Part”

func _init(p_part: String, p_price: float, p_calories: float):
type = “Chicken”
part = p_part
price_per_kg = p_price
calories_per_100g = p_calories

func get_description() -> String:
var base_desc = super.get_description()
return “%s, Part: %s” % [base_desc, part]

ジビエクラス:`Meat` を継承

ジビエも `Meat` クラスを継承し、その種類(鹿、猪など)や産地といった固有の情報を持ちます。

class Gibier extends Meat:
var gibier_type: String = “Unknown Gibier”
var origin: String = “Unknown Origin”

func _init(p_gibier_type: String, p_origin: String, p_price: float, p_calories: float):
type = “Gibier”
gibier_type = p_gibier_type
origin = p_origin
price_per_kg = p_price
calories_per_100g = p_calories

func get_description() -> String:
var base_desc = super.get_description()
return “%s, Gibier Type: %s, Origin: %s” % [base_desc, gibier_type, origin]

ポリモーフィズム:統一されたインターフェースでの多様な振る舞い

ポリモーフィズム(多態性)は、異なるクラスのオブジェクトが、同じメソッド呼び出しに対して異なる振る舞いをすることです。これにより、コードはより汎用的になり、新しい種類の肉が追加されても、既存のコードを変更せずに対応できるようになります。

`get_description()` メソッドの活用

前述の例では、`Meat` クラスで `get_description()` メソッドを定義しました。各子クラスは、このメソッドをオーバーライド(再定義)することで、それぞれの肉の固有の情報を追加した説明を生成します。これにより、どの肉オブジェクトであっても `get_description()` を呼び出すだけで、その肉に特化した説明を得られます。

リストでの管理と処理

例えば、複数の肉製品の情報をリストに格納し、それぞれの説明を表示したい場合を考えます。ポリモーフィズムのおかげで、リスト内の各要素がどのクラスのインスタンスであっても、単一のループで `get_description()` を呼び出すことができます。

var meat_inventory = []
meat_inventory.append(Beef.new(“Ribeye”, 5000.0, 250.0, 5))
meat_inventory.append(Pork.new(“Berkshire”, 2000.0, 210.0))
meat_inventory.append(Chicken.new(“Thigh”, 800.0, 165.0))
meat_inventory.append(Gibier.new(“Venison”, “Hokkaido”, 6000.0, 150.0))

for meat_item in meat_inventory:
print(meat_item.get_description())

このコードは、`meat_inventory` リスト内の各 `meat_item` に対して `get_description()` を呼び出します。リストの要素が `Beef` であろうと `Gibier` であろうと、それぞれのクラスで定義された `get_description()` が実行され、適切な情報が表示されます。

利点

  • コードの簡潔化: 新しい肉の種類を追加するたびに、既存の処理コードを修正する必要がありません。
  • 拡張性: 新しい `Meat` の派生クラスを追加するのが容易になります。
  • 保守性: コードが整理され、理解しやすくなります。

まとめ

GDScriptにおける継承とポリモーフィズムは、現実世界の情報(牛肉、豚肉、鶏肉、ジビエなど)をモデル化する上で非常に強力なツールとなります。共通の基盤 (`Meat` クラス) を定義し、各具体的な肉の種類 (`Beef`, `Pork`, `Chicken`, `Gibier`) がそれを継承することで、コードの再利用性と構造化を実現できます。さらに、ポリモーフィズムを活用することで、これらの異なる肉オブジェクトを統一的な方法で扱い、柔軟で拡張性の高いシステムを構築することが可能になります。このアプローチは、ゲーム開発におけるアイテム管理、キャラクター情報、敵の種類などを扱う際にも同様に有効です。