Computer >> Máy Tính >  >> Lập trình >> Java

Làm thế nào để giải quyết vấn đề kim cương bằng cách sử dụng các phương thức mặc định trong Java?

Kế thừa là quan hệ giữa hai lớp trong đó một lớp kế thừa các thuộc tính của lớp kia. Mối quan hệ này có thể được xác định bằng cách sử dụng từ khóa mở rộng là -

public class A extends B{
}

Lớp kế thừa các thuộc tính được gọi là lớp con hoặc lớp con và lớp có các thuộc tính được kế thừa là lớp siêu hoặc, lớp cha.

Trong kế thừa, một bản sao của các thành viên siêu lớp được tạo ra trong đối tượng lớp con. Do đó, bằng cách sử dụng đối tượng lớp con, bạn có thể truy cập các thành viên của cả hai lớp.

Nhiều người thừa kế:

Có nhiều kiểu kế thừa khác nhau như đơn, đa cấp, phân cấp, đa cấp và kết hợp.

Trong đa kế thừa một lớp kế thừa các thuộc tính của nhiều lớp. Nói cách khác, trong đa kế thừa, chúng ta có thể có một lớp con và n số lớp cha. Java không hỗ trợ đa kế thừa (với các lớp).

Vấn đề kim cương

Ví dụ, chúng ta hãy giả sử rằng Java hỗ trợ đa kế thừa. Với giả định đó, hãy xem xét ví dụ sau.

Ví dụ

Ở đây, chúng ta có một lớp trừu tượng có tên là Mẫu với một phương thức trừu tượng là -

public class abstract Sample {
   public abstract demo();
}

Sau đó, trong cùng một gói / thư mục, chúng ta có hai lớp mở rộng lớp này và cố gắng triển khai phương thức trừu tượng của nó, demo ().

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");
   }  
}

Theo giả định của chúng tôi, vì Java hỗ trợ đa kế thừa, chúng tôi đang cố gắng kế thừa cả hai lớp Super1 và Super2.

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

Sau đó, theo quy tắc kế thừa cơ bản, một bản sao của cả hai phương thức demo () sẽ được tạo trong đối tượng lớp con để lại lớp con có hai phương thức có cùng nguyên mẫu (tên và đối số). Sau đó, nếu bạn gọi phương thức demo () bằng cách sử dụng đối tượng của trình biên dịch lớp con sẽ gặp phải tình huống mơ hồ không biết nên gọi phương thức nào. Sự cố này được gọi là sự cố kim cương trong Java.

Làm thế nào để giải quyết vấn đề kim cương bằng cách sử dụng các phương thức mặc định trong Java?

Do Java này không hỗ trợ đa kế thừa, tức là bạn không thể mở rộng nhiều hơn một lớp khác. Tuy nhiên, nếu bạn cố gắng làm như vậy, lỗi thời gian biên dịch sẽ được tạo ra.

Lỗi thời gian biên dịch

Khi biên dịch, chương trình trên tạo ra lỗi sau -

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

Giải pháp

Bạn có thể đạt được đa kế thừa trong Java, sử dụng các phương thức và giao diện mặc định (Java8).

Từ Java8 trên các phường phương pháp mặc định được giới thiệu trong một giao diện. Không giống như các phương thức trừu tượng khác, đây là các phương thức của một giao diện có cài đặt mặc định. Nếu bạn có phương thức mặc định trong một giao diện, bạn không bắt buộc phải ghi đè (cung cấp nội dung) nó trong các lớp đã triển khai giao diện này.

Bạn có thể có các phương thức mặc định giống nhau (cùng tên và chữ ký) trong hai giao diện khác nhau và từ một lớp, bạn có thể triển khai hai giao diện này.

Nếu bạn làm như vậy, bạn phải ghi đè phương thức mặc định từ lớp chỉ định rõ ràng phương thức mặc định cùng với tên giao diện của nó.

Ví dụ

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();
   }
}

Đầu ra

display method of MyInterface1
display method of MyInterface2