インターフェース (3) 多重継承


[インターフェース 関連記事]

今回はインタフェースによる多重継承をみていきます。

多重継承とは

複数のクラスから継承することを多重継承といいます。Javaでは複数のクラスからの多重継承は認められていません。クラスの多重継承が認められれば、スーパークラスのメンバに同じ名前があった場合、「どちらのメンバを継承するのか」などややこしい問題が出てきます。
それに対してインターフェースは、メソッドの宣言だけを行い具体的な処理がない抽象メソッドでした。具体的な処理はインターフェースの実装クラスで記述するので、同じメソッド名を継承しても問題ありません。

クラスとインターフェースの継承(1)

【SuperClass.java】

class SuperClass{
    void method(){
    	System.out.println("スーパークラス : メソッド");
    }
}

【InterfaceSample.java】

interface InterfaceSample {
	void method2();
}

【SubClass.java】

class SubClass extends SuperClass implements InterfaceSample{
    //メソッド
    public void method2(){  //オーバーライド
    	System.out.println("サブクラス : メソッド");
    }
}

java093

クラスとインタフェースを同時に継承しています。class宣言のときに「extends」と「implements」の両方のキーワードを用いるわけですが、「extends」の方を先に書かないと構文エラーになります。

class サブクラス名 extends スーハー゚クラス名 implementes インターフェース名

インターフェースのメソッドは抽象メソッドなのでオーバーライドする必要があります。抽象メソッドは具体的な処理が記述されていないメソッドであり、実装クラスでオーバーライドして具体的な処理を記述することを強制しています。

【Sample.java】

public class Sample{
    public static void main(String[] args) {
    	SubClass obj = new SubClass();
    	obj.method();
    	obj.method2();
    }
}
スーパークラス : メソッド
サブクラス : メソッド

4行目はスーパークラス「SubClass」から継承してそのまま使っています。
5行目はインターフェース「InterfaceSample」から継承したメソッドをサブクラス「SubClass」でオーバーライドしています。
インターフェースのメソッドは実装クラスでオーバーライドしないといけないので多重継承としては少し微妙ですが、一応Javaでの多重継承となります。インターフェースの性質上、インターフェースは「実装クラスで宣言しなければならない最低限のメソッドを指示している」と考えた方がわかりやすいですが。。。

クラスとインターフェースの継承(2)

【SuperClass.java】

class SuperClass{
    void method(){
    	System.out.println("スーパークラス : メソッド");
    }
}

【InterfaceSample.java】

interface InterfaceSample {
	void method();
}

【SubClass.java】

class SubClass extends SuperClass implements InterfaceSample{
}

次はスーパークラスとインターフェースに同じメソッド名がある場合、どのような処理がされるかみていきます。サブクラス「SubClass」には、インターフェースのメソッドをあえてオーバーライドしませんでした。結果はどのようになるかというと、

Exception in thread "main" java.lang.Error:
                     Unresolved compilation problem:
継承メソッド SuperClass.method() は InterfaceSample 内の
public 抽象メソッドを隠蔽できません

とエラーになりました。スーパークラスに具体的な処理が記述されているので、こちらを優先してくれることを期待したのですが、期待に反して「継承メソッドより抽象メソッドの方が強い」という結果です。ということでインターフェースのメソッドは必ずオーバーライドする必要があります。

複数のインターフェースの継承

【InterfaceSample.java】

interface InterfaceSample {
	void method();
}

【InterfaceSample2.java】

interface InterfaceSample2 {
	void method2();
}

【SubClass.java】

class SubClass implements InterfaceSample , InterfaceSample2{
	public void method (){
		System.out.println("InterfaceSample メソッド");
	}
	public void method2(){
		System.out.println("InterfaceSample2メソッド");
	}
}

複数のインターフェースを実装したい場合は、「implements」キーワードの後に実装したいインターフェース名をカンマ区切りで並べるだけです。

class サブクラス名  implementes インターフェース名 , インターフェース名2 , ・・・

実装クラスでは全てのインターフェースのメソッドをオーバーラードする必要があります。また複数のインターフェースを実装すると同じ抽象メソッド名が継承される場合がありますが、特に気にする必要はありません。インターフェースなのでメソッドには具体的な処理はどれも記述されてませんし、実装クラスでオーバーライドします。どのインターフェースから継承するかは問題になりません。


[インターフェース 関連記事]

「インターフェース (3) 多重継承」への1件のフィードバック

  1. ゲームを制作している際にクラスとインターフェースの継承(2)と同じような症状に悩まされていた者ですが(私の場合は同様のエラーが出る場合と出ない場合があり悩まされていました)

    おそらく上の例で問題なのはスーパークラスで実装されているメソッドにアクセス修飾子を宣言していないためにアクセスレベルがデフォルトになっていることにあると思います

    インターフェースの特性上インターフェースで宣言されるメソッドにはアクセスレベルがpublicの実装が必要になります

    なので上の例ではスーパークラスのメソッドmethodのアクセスレベルをpublicにすればエラーが発生しないようになると思います

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です