Computer >> Hướng Dẫn Máy Tính >  >> Lập Trình >> Java

Giải quyết vấn đề Diamond Problem (Vấn đề kim cương) bằng default method trong Java

Kế thừa (Inheritance) là mối quan hệ giữa hai class, một class kế thừa thuộc tính của class kia. Định nghĩa bằng từ khóa extends:

public class A extends B { }

Class kế thừa gọi là sub/child class, class được kế thừa gọi là super/parent class. Trong kế thừa, bản sao thành viên super class được tạo trong sub class object → dùng sub class object truy cập cả hai class.

Đa kế thừa (Multiple Inheritance)

Có các loại: đơn, đa cấp, phân cấp, đa kế thừa, lai. Trong đa kế thừa, một class kế thừa nhiều class. Tức là một child class và n parent class. Java KHÔNG hỗ trợ đa kế thừa (với class).

Vấn đề kim cương (Diamond Problem)

Giả sử Java hỗ trợ đa kế thừa. Xét ví dụ:

  • Abstract class Sample có abstract method demo()
  • Hai class Super1, Super2 extends Sample và implement demo() khác nhau
  • Class SubClass extends Super1, Super2 → có 2 method demo() cùng signature
  • Gọi obj.demo() → compiler ambiguous không biết gọi method nào → Diamond Problem

Giải quyết vấn đề Diamond Problem (Vấn đề kim cương) bằng default method trong Java

Do đó Java không hỗ trợ đa kế thừa class. Nếu thử compile sẽ lỗi:

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

Giải pháp

Dùng default method (Java 8) và interface để đạt đa kế thừa.

  • Từ Java 8, interface có default method (có implementation mặc định)
  • Không bắt buộc override default method trong class implement
  • Có thể có cùng default method trong 2 interface khác nhau
  • Class implement 2 interface đó → BẮT BUỘC override default method, chỉ định rõ interface: MyInterface1.super.display() hoặc MyInterface2.super.display()

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();
        // hoặc 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