Đơn thừa kế trong java với ví dụ cụ thể

Thừa kế một tính năng quan trọng trong lập trình hướng đối tượng. Thông thường ở các ngôn ngữ khác như C/C++ chúng ta sẽ có đơn thừa kế và đa thừa kế. Nhưng với ngôn ngữ java chỉ hỗ trợ đơn thừa kế.

Diamond Problem

Trong đa thừa kế chúng ta sẽ gặp tình huống, giữa các class được thừa kế có những thuộc tính và method cùng tên.

Trong trường hợp trên, đối với những thuộc tính và method có cùng tên thì class con sẽ không biết sử dụng của class cha nào. Được gọi là Diamond Problem.

Cùng theo dõi ví dụ sau

// File A.java
public class A
{
public void disp()
{
System.out.println("A disp() called");
}
}
// File B.java
public class B extends A
{
@Override
public void disp()
{
System.out.println("B disp() called");
}
}
// File C.java
public class C extends A
{
@Override
public void disp()
{
System.out.println("C disp() called");
}
}
// File D.java
// Với file D chúng ta sẽ gặp lỗi compile vì D không được thừa kế từ 2 class cha đâu nhé.
public class D extends B,C
public static void main(String args[])
{
D d = new D();
d.disp();
}
}
// File A.java public class A { public void disp() { System.out.println("A disp() called"); } } // File B.java public class B extends A { @Override public void disp() { System.out.println("B disp() called"); } } // File C.java public class C extends A { @Override public void disp() { System.out.println("C disp() called"); } } // File D.java // Với file D chúng ta sẽ gặp lỗi compile vì D không được thừa kế từ 2 class cha đâu nhé. public class D extends B,C public static void main(String args[]) { D d = new D(); d.disp(); } }
// File A.java
public class A
{
    public void disp()
    {
        System.out.println("A disp() called");
    }
}

// File B.java
public class B extends A
{
    @Override
    public void disp()
    {
        System.out.println("B disp() called");
    }
}
// File C.java
public class C extends A
{
    @Override
    public void disp()
    {
        System.out.println("C disp() called");
    }
}
// File D.java 
// Với file D chúng ta sẽ gặp lỗi compile vì D không được thừa kế từ 2 class cha đâu nhé.
public class D extends B,C
   public static void main(String args[])
   {
       D d = new D();
       d.disp(); 
  }
}

Đơn thừa kế

Ở trên chúng ta có class B và C entends A và chúng override lại method disp(). Đều này là hoàn toàn hợp lệ.

Thế nhưng D lại extends của B, C đều này là không được phép. Chúng ta cả B, C đều có method disp(). Class D sẽ không biết dùng method disp() của thằng nào. Kết quả chúng ta sẽ bị lỗi biên dịch.

Đa thừa kế trong java

Đọc tiêu đề có vẽ lạ, thằng này mới vừa nảy nói java chỉ hỗ trợ đơn thừa, giờ lại đa thừa kế gì nữa đây =).

Đúng thật, java chỉ hỗ trợ đơn thừa kế. Thế nhưng không cách này thì cách khác, chúng sẽ biến tấu một xíu để có một đa thừa kế trong java không chính thống. 

Note: Có rất nhiều cách để implement đa thừa kế trong java, đây chỉ là cách của mình theo kinh nghiệm mình đã từng làm trong java thôi nhé. Các bạn có thể tự đề ra mô hình cho mình và triển khai nó trên dự án của bạn.

đa thừa kế trong java

Chúng ta cần nhớ lại một chút kiến thức về abstract class, interface và quan hệ has – a trong java.
Chúng ta sẽ có class D extends A, tới đây chúng ta mới chỉ có đơn thừa kế. Chúng ta có interface B và một class C sẽ implement B. Sau đó chúng ta chỉ cần khai báo trong B thuộc tính B và khởi tạo object C cho B.

// File Car.java
public class Car {
void dispCategory(){
System.out.println("Car");
}
}
// File Car.java public class Car { void dispCategory(){ System.out.println("Car"); } }
// File Car.java
public class Car {
    void dispCategory(){
        System.out.println("Car");
    }
}
// File Vehicle.java
public interface Vehicle {
void maxSpeed();
}
// File Vehicle.java public interface Vehicle { void maxSpeed(); }
// File Vehicle.java
public interface Vehicle {
    void maxSpeed();
}
public class VehicleImpl implements Vehicle {
@Override
public void maxSpeed() {
System.out.println("Max speed is 200km/h");
}
}
public class VehicleImpl implements Vehicle { @Override public void maxSpeed() { System.out.println("Max speed is 200km/h"); } }
public class VehicleImpl implements Vehicle {
    @Override
    public void maxSpeed() {
        System.out.println("Max speed is 200km/h");
    }
}
// File Bus.java
public class Bus extends Car {
Vehicle vehicle;
Bus() {
vehicle = new VehicleImpl();
}
void getSpeed() {
dispCategory();
vehicle.maxSpeed();
}
}
// File Bus.java public class Bus extends Car { Vehicle vehicle; Bus() { vehicle = new VehicleImpl(); } void getSpeed() { dispCategory(); vehicle.maxSpeed(); } }
// File Bus.java
public class Bus extends Car {
    Vehicle vehicle;

    Bus() {
        vehicle = new VehicleImpl();
    }

    void getSpeed() {
        dispCategory();
        vehicle.maxSpeed();
    }
}
// File Main.java
public class Main {
public static void main(String[] args) {
Bus bus = new Bus();
bus.getSpeed();
}
}
// File Main.java public class Main { public static void main(String[] args) { Bus bus = new Bus(); bus.getSpeed(); } }
// File Main.java
public class Main {
    public static void main(String[] args) {
        Bus bus = new Bus();
        bus.getSpeed();
    }
}

Output: 

Car
Max speed is 200km/h

5 1 vote
Article Rating
Subscribe
Notify of
guest


4 Comments
Newest
Oldest Most Voted
Inline Feedbacks
View all comments
4
0
Would love your thoughts, please comment.x
()
x