Java
 Computer >> コンピューター >  >> プログラミング >> Java

Javaのデフォルトメソッドを使用して菱形継承問題を解決するにはどうすればよいですか?


継承 1つのクラスが他のクラスのプロパティを継承する2つのクラス間の関係です。この関係は、extendsキーワードを使用して-

として定義できます。
public class A extends B{
}

プロパティを継承するクラスはサブクラスまたは子クラスと呼ばれ、プロパティを継承するクラスはスーパークラスまたは親クラスです。

継承では、スーパークラスメンバーのコピーがサブクラスオブジェクトに作成されます。したがって、サブクラスオブジェクトを使用すると、両方のクラスのメンバーにアクセスできます。

複数の遺産:

利用可能な継承には、単一、マルチレベル、階層、複数、およびハイブリッドのさまざまなタイプがあります。

多重継承では、1つのクラスが複数のクラスのプロパティを継承します。言い換えると、多重継承では、1つの子クラスとn個の親クラスを持つことができます。 Javaは(クラスを使用した)多重継承をサポートしていません。

菱形継承問題

たとえば、Javaが多重継承をサポートしていると仮定しましょう。その仮定で、次の例を考えてみましょう。

ここに、 Sampleという名前の抽象クラスがあります。 -

のような抽象的なメソッドを使用します
public class abstract Sample {
   public abstract demo();
}

次に、同じパッケージ/フォルダに、このクラスを拡張し、その抽象メソッド demo()を実装しようとしている2つのクラスがあります。

public class Super1 extends Sample{
   public void demo() {
      System.out.println("demo method of super1");
   }  
}
public class Super2 extends Sample{
   public void demo() {
      System.out.println("demo method of super2");
   }  
}

私たちの仮定によれば、Javaは多重継承をサポートしているため、Super1とSuper2の両方のクラスを継承しようとしています。

public class SubClass extends Super1, Super2 {  
   public static void main(String args[]) {
      SubClass obj = new SubClass();
      obj.demo();
   }
}

次に、継承の基本ルールに従って、両方のdemo()メソッドのコピーをサブクラスオブジェクトに作成し、同じプロトタイプ(名前と引数)を持つ2つのメソッドをサブクラスに残します。次に、サブクラスコンパイラのオブジェクトを使用してdemo()メソッドを呼び出すと、呼び出すメソッドがわからないというあいまいな状況に直面します。この問題は、Javaでは菱形継承問題として知られています。

Javaのデフォルトメソッドを使用して菱形継承問題を解決するにはどうすればよいですか?

このため、Javaは多重継承をサポートしていません。つまり、他の複数のクラスを拡張することはできません。それでも、そうしようとすると、コンパイル時エラーが生成されます。

コンパイル時エラー

コンパイル時に、上記のプログラムは次のエラーを生成します-

MultipleInheritanceExample.java:9: error: '{' expected
public class MultipleInheritanceExample extends MyInterface1, MyInterface2{
                                                            ^
1 error

解決策

デフォルトのメソッド(Java8)とインターフェースを使用して、Javaで多重継承を実現できます。

Java8以降のデフォルトのメソッド インターフェイスに導入されます。他の抽象メソッドとは異なり、これらはデフォルトの実装を持つインターフェースのメソッドです。インターフェイスにデフォルトのメソッドがある場合、このインターフェイスをすでに実装しているクラスでそれをオーバーライド(本文を提供)する必要はありません。

2つの異なるインターフェースで同じデフォルトのメソッド(同じ名前と署名)を持つことができ、クラスからこれら2つのインターフェースを実装できます。

その場合は、デフォルトのメソッドとそのインターフェース名を明示的に指定して、クラスのデフォルトのメソッドをオーバーライドする必要があります。

interface MyInterface1{  
   public static int num = 100;
   public default void display() {
      System.out.println("display method of MyInterface1");
   }
}
interface MyInterface2{  
   public static int num = 1000;
   public default void display() {
      System.out.println("display method of MyInterface2");
   }
}  
public class InterfaceExample implements MyInterface1, MyInterface2{
   public void display() {
      MyInterface1.super.display();
      //or,
      MyInterface2.super.display();
   }      
   public static void main(String args[]) {
      InterfaceExample obj = new InterfaceExample();
      obj.display();
   }
}

出力

display method of MyInterface1
display method of MyInterface2

  1. Javaでファイルユーティリティメソッドを使用してディレクトリを作成するにはどうすればよいですか?

    Java 7以降、File.02sクラスが導入されました。これには、ファイル、ディレクトリ、またはその他のタイプのファイルを操作する(静的)メソッドが含まれています。 createDirectory() ファイルのメソッド クラスは必要なディレクトリのパスを受け入れ、新しいディレクトリを作成します。 例 次のJavaの例では、作成するディレクトリのパスと名前をユーザーから読み取り、作成します。 import java.io.IOException; import java.nio.file.Files; import java.nio.file.Path; import java.nio

  2. Java 9でJShellのデフォルトエディタを変更するにはどうすればよいですか?

    JShell REPLを実装します (Read-Evaluate-Print Loop)コマンドラインからコードを読み取ります 、指定されたスニペットを評価し、結果を出力します。 JShellでは、JShellエディターパッドを使用して、デフォルトのJShellエディターからコードを編集できます。 。 「/set」も使用できます 別のエディタを定義するためにデフォルトのエディタを変更するコマンド。「/edit」を起動するとき コマンド、このエディターを使用できます。この操作を実行するには、 / set editor [editor]を起動するだけです。 コマンド。 メモ帳を設定するとし