[Tự học Java] Tính kế thừa(Inheritance) trong Java » https://final-blade.com

Trong bài hướng dẫn này, tất cả chúng ta sẽ khám phá về tính thừa kế trong Java bằng vài ví dụ trợ giúp .

Tính kế thừa(Inheritance) là một trong những tính năng quan trọng của lập trình hướng đối tượng. Nó cho phép chúng ta định nghĩa một class mới từ một class đang tồn tại. Lấy ví dụ,

/**
* Cafedev.vn - Kênh thông tin IT hàng đầu Việt Nam
*
* @author cafedevn
* Contact: [email protected]
* Fanpage: https://www.facebook.com/cafedevn
* Instagram: https://instagram.com/cafedevn
* Twitter: https://twitter.com/CafedeVn
* Linkedin: https://www.linkedin.com/in/cafe-dev-407054199/
*/

class Animal
{
    // eat() method
    // sleep() method
}
class Dog extends Animal
{
    // bark() method
}

Trong Java, tất cả chúng ta sử dụng từ khóa extends để thừa kế từ một class. Ở đây tất cả chúng ta thừa kế class Dog từ class Animal .
Class Animal là superclass ( class cha hoặc class cơ sở ), và class dog là một subclass ( class con hay class dẫn xuất ). Subclass thừa kế những phương pháp và field của superclass .

Mối quan hệ is-a (là-một) 

Tính kế thừa là một mối quan hệ is-a (là-một). Chúng ta chỉ sử dụng tính kế thừa chỉ khi một mối quan hệ is-a xuất hiện giữa hai class. 

Đây là vài ví dụ :

  • Ô tô là một phương tiện.
  • Cam là một loại quả
  • Giải phẫu viên là một bác sĩ.
  • Chó là một con vật 

1. Ví dụ 1: Tính kế thừa trong Java

/**
* Cafedev.vn - Kênh thông tin IT hàng đầu Việt Nam
*
* @author cafedevn
* Contact: [email protected]
* Fanpage: https://www.facebook.com/cafedevn
* Instagram: https://instagram.com/cafedevn
* Twitter: https://twitter.com/CafedeVn
* Linkedin: https://www.linkedin.com/in/cafe-dev-407054199/
*/

class Animal {

   public void eat() {
      System.out.println("I can eat");
   }

   public void sleep() {
      System.out.println("I can sleep");
   }
}

class Dog extends Animal {
   public void bark() {
      System.out.println("I can bark");
   }
}

class Main {
   public static void main(String[] args) {

      Dog dog1 = new Dog();

      dog1.eat();
      dog1.sleep();

      dog1.bark();
   }
}

Khi ta chạy chương trình, tác dụng sẽ là :

I can eat
I can sleep
I can bark

Ở đây, tất cả chúng ta đã cho thừa kế subclass Dog từ superclass Animal. Class Dog thừa kế những phương pháp eat ( ) and sleep ( ) từ class Animal
Do đó, những đối tượng người dùng của class Dog hoàn toàn có thể truy vấn những thành viên của cả class Dog và class Animal

Từ khóa protected trong Java

Chúng ta đã tìm hiểu và khám phá về private và public access modifier trong những bài hướng dẫn trước đây .
Thành viên private chỉ hoàn toàn có thể được truy vấn từ bên trong class
Các thành viên public thì hoàn toàn có thể được truy vấn từ bất kỳ đâu
Bạn cũng hoàn toàn có thể định nghĩa phương pháp và những tài liệu của đối tượng người dùng là chính sách protected. Các thành viên protected hoàn toàn có thể truy vấn được :

  • Từ bên trong class
  • Bên trong các subclass
  • Trong cùng một gói(package)

Đây là một bản tổng kết từ nơi mà những access modifier hoàn toàn có thể được truy vấn .

  Class Package subclass World
public Yes Yes Yes Yes
private Yes No No No
protected Yes Yes Yes No

2. Ví dụ 2: Từ khóa protected

/**
* Cafedev.vn - Kênh thông tin IT hàng đầu Việt Nam
*
* @author cafedevn
* Contact: [email protected]
* Fanpage: https://www.facebook.com/cafedevn
* Instagram: https://instagram.com/cafedevn
* Twitter: https://twitter.com/CafedeVn
* Linkedin: https://www.linkedin.com/in/cafe-dev-407054199/
*/

class Animal {
   protected String type;
   private String color;

   public void eat() {
      System.out.println("I can eat");
   }

   public void sleep() {
      System.out.println("I can sleep");
   }

   public String getColor(){
      return color;
   }

   public void setColor(String col){
      color = col;
   }
}

class Dog extends Animal {
   public void displayInfo(String c){
      System.out.println("I am a " + type);
      System.out.println("My color is " + c);
   }
   public void bark() {
      System.out.println("I can bark");
   }
}

class Main {
   public static void main(String[] args) {

      Dog dog1 = new Dog();
      dog1.eat();
      dog1.sleep();
      dog1.bark();
 
      dog1.type = "mammal";
      dog1.setColor("black");
      dog1.displayInfo(dog1.getColor()); 
   }
}

Khi chay chương trình, hiệu quả sẽ là :

I can eat
I can sleep
I can bark
I am a mammal
My color is black

Ở đây, dữ liệu type bên trong class Animal được bảo vệ. chúng ta vừa truy cập dữ liệu này từ class Main sử dụng đoạn code:

dog1.type = "mammal";

Điều này hoàn toàn có thể xảy ra do tại class Animal và class Main bên trong cùng một gói ( chung file ) .

3. Ghi đè(overriding) phương thức trong Java

Từ những ví dụ ở trên, tất cả chúng ta biết rằng những đối tượng người tiêu dùng của một subclass cũng hoàn toàn có thể truy vấn những phương pháp trong superclass của nó .

Điều gì sẽ xảy ra nếu một phương thức chung được định nghĩa bên trong cả superclass và subclass?

Trong trường hợp đó, phương pháp ở bên trong subclass sẽ ghi đè lên phương pháp ở trong superclass. Lấy ví dụ như :

4. Ví dụ 3: Ví dụ về ghi đè phương thức 

/**
* Cafedev.vn - Kênh thông tin IT hàng đầu Việt Nam
*
* @author cafedevn
* Contact: [email protected]
* Fanpage: https://www.facebook.com/cafedevn
* Instagram: https://instagram.com/cafedevn
* Twitter: https://twitter.com/CafedeVn
* Linkedin: https://www.linkedin.com/in/cafe-dev-407054199/
*/

class Animal {
   protected String type = "animal";

   public void eat() {
      System.out.println("I can eat");
   }

   public void sleep() {
      System.out.println("I can sleep");
   }
}

class Dog extends Animal {
  
   @Override
   public void eat() {
      System.out.println("I eat dog food");
   }

   public void bark() {
      System.out.println("I can bark");
   }
}

class Main {
   public static void main(String[] args) {

      Dog dog1 = new Dog();
      dog1.eat();
      dog1.sleep();
      dog1.bark();
   }
}

Kết quả khi chạy chương trình sẽ là :

I eat dog food
I can sleep
I can bark

Ở đây, phương pháp eat ( ) vừa Open bên trong superclass Animal và vừa Open bên trong subclass dog. Chúng ta đã khởi tạo một đối tượng người dùng là dog1 của subclass dog .
Khi tất cả chúng ta gọi phương pháp eat ( ) sử dụng đối tượng người dùng dog1, phương pháp bên trong class Dog sẽ được gọi, và phương pháp tương tự như trong superclass sẽ không được gọi. Điều này được gọi là ghi đè phương pháp .
Trong ví dụ trên, tất cả chúng ta đã sử dụng thẻ @ Override để báo cho trình biên dịch rằng chúng ra đang ghi đè một phương pháp. Tuy nhiên, điều này lại không bắt buộc. Chúng ta sẽ khám phá về ghi đè phương pháp chi tiết cụ thể hơn trong bài hương dẫn tiếp nối .
Nếu tất cả chúng ta cần gọi phương pháp eat ( ) của class Animal, tất cả chúng ta cần sử dụng từ khóa super

5. Ví dụ 4: từ khóa super trong Java

/**
* Cafedev.vn - Kênh thông tin IT hàng đầu Việt Nam
*
* @author cafedevn
* Contact: [email protected]
* Fanpage: https://www.facebook.com/cafedevn
* Instagram: https://instagram.com/cafedevn
* Twitter: https://twitter.com/CafedeVn
* Linkedin: https://www.linkedin.com/in/cafe-dev-407054199/
*/

class Animal {
   public Animal() {
     System.out.println("I am an Animal");
   }

   public void eat() {
     System.out.println("I can eat");
   }
}

class Dog extends Animal {
   public Dog(){
      super();
      System.out.println("I am a dog");
   }

  @Override
  public void eat() {
     super.eat();
     System.out.println("I eat dog food");
  }

   public void bark() {
      System.out.println("I can bark");
   }
}

class Main {
   public static void main(String[] args) {
      Dog dog1 = new Dog();

      dog1.eat();
      dog1.bark();
   }
}

Kết quả khi chạy chương trình là :

I am an Animal
I am a dog
I can eat
I eat dog food
I can bark

Ở đây, chúng ra đã sử dụng từ khóa super để gọi hàm tạo sử dụng phương pháp super ( ). Đồng thời tất cả chúng ta cũng gọi phương pháp eat ( ) của superclass Animal sử dụng super.eat ( ) .
Hãy chú ý quan tâm đến sự độc lạ giữa việc sử dụng từ khóa super khi gọi hàm tạo và phương pháp. Để khám phá thêm, hãy tìm hiểu thêm từ khóa super trong Java .

6. Các kiểu kế thừa

Có năm kiểu kế thừa. 

  • Kiểu đơn kế thừa (Single inheritance) – Class b chỉ mở rộng từ class a
  • Kiểu kế thừa nhiều cấp (Multilevel inheritance) – Class b mở rộng từ class a, sau đó class c mở rộng từ class b
  • Kiểu kế thừa thứ bậc (Hierachical inheritance) – Class a là superclass cho các class b, c, và d.
  • Kiểu đa kế thừa (Multiple inheritance) – Class c mở rộng từ giao diện a và b
  • Kiểu kế thừa lai (Hybrid inheritance) – Kết hợp hai hay hiều kiểu kế thừa.

Java không tương hỗ kiểu đa thừa kế và kiểu thừa kế lai trải qua những class. Tuy nhiên, tất cả chúng ta vẫn hoàn toàn có thể đạt được tính đa thừa kế trong Java trải qua những interface. Chúng ta sẽ khám phá về những interface trong những chương tiếp theo .

7. Tại sao phải sử dụng tính kế thừa?

Điều quan trọng nhất của việc sử dụng tính thừa kế là năng lực tái sử dụng code. Các code Open trong class cha không cần phải viết lại trong class con .

Việc sử dụng tính kế thừa giúp đạt được tính đa hình trong thời gian chạy chương trình thông qua việc ghi đè phương thức. Chúng ta sẽ tìm hiểu về tính đa hình trong các chương tiếp theo.

Đăng ký kênh youtube để ủng hộ Cafedev nha các bạn, Thanks you!