WisdomSoft - for your serial experiences.

継承

既存のクラスから機能を引き継ぎ、新しい機能を追加する「継承」について解説します。継承はオブジェクト指向を理解する上で重要な概念で、継承によるコードの分離と抽象化によって、再利用可能で変更に強いプログラムを表現できます。

基本クラスと派生クラス

継承(iheritance)はオブジェクト指向を構成する主要な概念の 1 つです。継承によって、複雑な構造のプログラムを階層ごとに分離し、機能を抽象化できます。これによって、プログラムの部品化と再利用が容易になり、コードの変更や機能の追加にも柔軟になります。

継承とは、あるクラスの機能を引き継ぐ新しいクラスを生成することです。 新たに生成されたクラスは、元のクラスが公開するメンバを最初から持ち、これに加えて新しいメンバを追加できます。元のクラスの機能を拡張するようなものです。

このとき、継承元となるクラスを基本クラス(base class)と呼び、 基本クラスを継承した新しいクラスを派生クラス(derived class)と呼びます。派生クラスは基本クラスのメンバを引き継ぐため、最初から基本クラスと同等の機能を持ち、これに加えて新しいメンバを自身の本体に記述できます。

クラスを継承するには、クラス宣言でクラス名に続いてコロン記号 : と継承元となる基本クラスを指定します。

派生クラスの宣言
クラス修飾子 class クラス名 : 基本クラス

基本クラスを指定するコロン記号 : 以降の部分を class base 指定(class base specification)と呼びます。宣言されたクラスは、指定された基本クラスを継承します。ただし、静的クラスを継承することはできません。有効なインスタンスメンバを持たない静的クラスを継承しても意味がないためです。

継承は、共通の操作を持つ異なるオブジェクトを表す時に使用できます。例えば RPG のようなゲームにおけるアイテムには「名前」や「値段」などの共通のメンバがあります。これを個別に作るのは効率が悪いので、共通の「アイテム」クラスを用意し、ここから「武器」クラスや「防具」クラスを用意すれば、共通部分を継承しながら、独自の機能を拡張していけます。

class Item
{
	public string Name { get; set; }
	public int Prise { get; set; }
}

class Weapon : Item
{
	public int AttackPoint { get; set; }
}

class Armor : Item
{
	public int DefensePoint { get; set; }
}

上記のコードは共通の機能をまとめた Item クラスを基本クラスとし、ここから派生する Weapon クラスと Armor クラスを作成しています。Weapon クラスも Armor クラスも、どちらも Item クラスの機能を引き継いでいるため Name プロパティと Prise プロパティを使えます。

コード1
class LostLogia
{
    public string Name { get; set; }
}

class JewelSeed : LostLogia
{
    public int SerialNember { get; set; }
}

class Test
{
    public static void Main(string[] args)
    {
        JewelSeed jewelSeed15 = new JewelSeed();
        jewelSeed15.Name = "ジュエルシード XV";
        jewelSeed15.SerialNember = 15;

        System.Console.WriteLine("Name=" + jewelSeed15.Name);
        System.Console.WriteLine("SerialNember=" + jewelSeed15.SerialNember);
    }
}
実行結果
コード1 実行結果

コード1の JewelSeed クラスは LostLogia クラスを継承しています。Main() メソッド内で JewelSeed クラスのインスタンスを作成し、Name プロパティと SerialNumber プロパティに値を設定し、結果を出力しています。

JewelSeed クラスのメンバ宣言では SerialNember プロパティしか宣言していませんが、Name プロパティが使える点に注目してください。JewelSeed クラスは LostLogia クラスを継承しているため、基本クラスである LostLogia クラスの機能を引き継いでいます。JewelSeed クラスの本体には Name プロパティが宣言されていませんが、基本クラスの Name プロパティを継承しているため JewelSeed オブジェクトは Name プロパティと SerialNember プロパティを利用できます。

一部のオブジェクト指向型言語(C++など)では、「多重継承」と呼ばれる複雑なクラス階層を持つことがあります。 多重継承は、複数の基本クラスを持つ派生クラスを生成することです。 C# で記述するならば、次のような形になります。

 class A {}
class B {}
class C : A, B {}

これは C クラスが A クラスと B クラスを継承していることを表しているように見えますが、C# では多重継承が禁止されており、複数の基本クラスを指定することはできません。上のようなコードは、コンパイルエラーとなります。多重継承は、クラスの継承関係が複雑になり、メンバの重複を生み出しすといった問題があります。例えば、次の多重継承には大きな問題があります。

class A {}
class B : A {}
class C : A {}
class D : B, C {}

 このとき D クラスは B クラスと C クラスを継承していますが、B クラスと C クラスは A クラスを継承しています。この場合、D クラスは B クラスと C クラスが継承する A クラスの機能を重複して継承してしまいます。

標準的なオブジェクト指向設計の範囲であれば、単一継承だけで適切に機能の部品化や抽象化が行えるため、近代的なプログラミング言語の多くは多重継承を禁止しており、常に 1 つの基本クラスから派生する単一継承モデルを採用しています。