#pragma twice

KAB-studio > プログラミング > Javaのオブジェクト指向入門 > 6. 継承Q and A > 6.3 2つのクラスをくっつけられる?
 
前のページへつぎ

6.3 2つのクラスをくっつけられる?

del.icio.us 登録する はてなブックマーク 詳細を表示 はてなブックマーク ブックマーク数 livedoorクリップ 詳細を表示 livedoorクリップ ブックマーク数 Yahoo!ブックマーク 詳細を表示 users RSSに登録
更新日: 2008/04/07
動作確認環境:Windows XP Professional SP2, Java SE 5

クラスをくっつけ……られない!

 質問:2つのスーパークラスから1つのサブクラスを作ることができますか?
 解答:できません。

 スーパークラスを複数使って1つのサブクラスを作ることを「多重継承」と言います。
 多重継承することで、複数のクラスの機能を組み合わせたすごいクラスを作ることができます。
 ……が、実はこの多重継承、できません

// MultipleInheritSubRunner.java

/**
 * 普通のクラスA。
 * フィールドをひとつ持ちます。
 */
class SuperA
{
    int data;
}

/**
 * 普通のクラスB。
 * フィールドをひとつ持ちます。
 */
class SuperB
{
    int data;
}

/**
 * SuperAクラスとSuperBクラスから継承した、サブクラス。
 * ……こんなクラスは作れません!
 */
class MultipleInheritSub extends SuperA, SuperB
{
}
// コンパイルエラー:
// MultipleInheritSubRunner.java:25: '{' がありません。
// class MultipleInheritSub extends SuperA, SuperB
// MultipleInheritSubRunner.java
/**
 * 普通のクラスA。
 * フィールドをひとつ持ちます。
 */
class SuperA
{
	int data;
}
/**
 * 普通のクラスB。
 * フィールドをひとつ持ちます。
 */
class SuperB
{
	int data;
}
/**
 * SuperAクラスとSuperBクラスから継承した、サブクラス。
 * ……こんなクラスは作れません!
 */
class MultipleInheritSub extends SuperA, SuperB
{
}
// コンパイルエラー:
// MultipleInheritSubRunner.java:25: '{' がありません。
// class MultipleInheritSub extends SuperA, SuperB

 まず、HasOneMethodSuper3クラスを用意します。

/**
 * 普通のクラス。
 * メソッド1つ持ちます。
 * (HasOneMethodSuperクラスと同じです)
 */
class HasOneMethodSuper3
{
    /**
     * 自クラスの名前を出力するメソッドです。
     */
    void printMyName()
    {
        System.out.println( "HasOneMethodSuper3" );
    }
}
/**
 * 普通のクラス。
 * メソッド1つ持ちます。
 * (HasOneMethodSuperクラスと同じです)
 */
class HasOneMethodSuper3
{
	/**
	 * 自クラスの名前を出力するメソッドです。
	 */
	void printMyName()
	{
		System.out.println( "HasOneMethodSuper3" );
	}
}

 MultipleInheritSubクラスは、SuperAクラスとSuperBクラスをスーパークラスに持つサブクラスです。
 でも、こんなクラスを作ろうとするとコンパイルエラーになってしまいます。

/**
 * SuperAクラスとSuperBクラスから継承した、サブクラス。
 * ……こんなクラスは作れません!
 */
class MultipleInheritSub extends SuperA, SuperB
{
}
// コンパイルエラー:
// MultipleInheritSubRunner.java:25: '{' がありません。
// class MultipleInheritSub extends SuperA, SuperB
/**
 * SuperAクラスとSuperBクラスから継承した、サブクラス。
 * ……こんなクラスは作れません!
 */
class MultipleInheritSub extends SuperA, SuperB
{
}
// コンパイルエラー:
// MultipleInheritSubRunner.java:25: '{' がありません。
// class MultipleInheritSub extends SuperA, SuperB

 もし作ることができたら、MultipleInheritSubクラスはSuperAクラスとSuperBクラスを組み合わせたクラスになります。
 MultipleInheritSubクラスのインスタンスを作ると、SuperAクラスとSuperBクラスのインスタンスが中に作られることになります。

 でも作ることができません。なぜできないようになっているのでしょう。

 それは、クラスの構造が複雑になるからです。
 たとえばこの例だと、SuperAクラスにdataフィールドが、さらにとSuperBクラスにもdataフィールドがあります、つまり両方にdataフィールドがあります
 そのため、サブクラスでdataフィールドを使う場合に「どのスーパークラスのdataフィールドか」ということを指定する必要があります。そうしないと、どっちのdataフィールドを使えばいいのかわからないからです。

 多重継承を許すと、クラスの構造が複雑になります。
 対して、多重継承できない場合(これを「単一継承」と言います)には、スーパークラスからサブクラスへ枝葉のように伸びていくシンプルな構造になります。

 (上がスーパークラス、下がサブクラスになります)
 多重継承の例の、クラスEのインスタンスを作ったら、どんなインスタンスが作られるのか想像もできません。そして、各クラスを使う場合には「このクラスのインスタンスの、このフィールド・メソッドを使う」と指定しなければいけなくなり、それはとても複雑なことになります。
 対して、単一継承なら複雑なことにはなりません。単一継承の例のクラスDは、インスタンスを作ればクラスCとクラスAのインスタンスを持ちます。ただ単にスーパークラスの方向に内包するだけなのでシンプルです。
 このように、単一継承の方が分かりやすいので、多重継承はできないようになっているわけです。

6.3 2つのクラスをくっつけられる?
このページは、Java言語を用いたオブジェクト指向プログラミングのチュートリアル解説を行う「Javaのオブジェクト指向入門」の一ページです。
詳しい説明は「Javaのオブジェクト指向入門」目次をご覧ください。