Bỏ qua để đến nội dung

Kế thừa (Inheritance)

Kế thừa (inheritance) cho phép một lớp (lớp con - subclass) tái sử dụng thuộc tính và phương thức của một lớp khác (lớp cha - superclass) bằng từ khóa extends:

public class Animal { // lớp cha
String name;
void eat() {
System.out.println(name + " đang ăn");
}
}
public class Dog extends Animal { // lớp con kế thừa Animal
void bark() {
System.out.println(name + " sủa: Gâu gâu!"); // dùng được "name" từ Animal
}
}
Dog dog = new Dog();
dog.name = "Lucky"; // thuộc tính kế thừa từ Animal
dog.eat(); // phương thức kế thừa từ Animal
dog.bark(); // phương thức riêng của Dog

Dog là một (is-a) Animal - mọi Dog cũng là một Animal, có đầy đủ những gì Animal có, cộng thêm phần riêng của nó.

2. super - gọi constructor/phương thức của lớp cha

Phần tiêu đề “2. super - gọi constructor/phương thức của lớp cha”
public class Animal {
String name;
public Animal(String name) {
this.name = name;
}
void eat() {
System.out.println(name + " đang ăn");
}
}
public class Dog extends Animal {
public Dog(String name) {
super(name); // gọi constructor của Animal - PHẢI là dòng đầu tiên
}
@Override
void eat() {
super.eat(); // gọi lại phiên bản eat() của Animal trước
System.out.println(name + " ăn rất nhanh!");
}
}

Lớp con có thể định nghĩa lại một phương thức đã có ở lớp cha, với cùng tên, cùng tham số - gọi là override (ghi đè). Dùng annotation @Override để trình biên dịch kiểm tra giúp bạn có ghi đè đúng chữ ký hay không:

public class Animal {
void makeSound() {
System.out.println("Một số âm thanh chung chung...");
}
}
public class Dog extends Animal {
@Override
void makeSound() { // ghi đè - cùng tên, cùng tham số với Animal
System.out.println("Gâu gâu!");
}
}

Chi tiết về sự khác nhau giữa override và overload xem ở trang “Overriding vs Overloading” trong mục What the Java!.

4. Java chỉ hỗ trợ đơn kế thừa (single inheritance)

Phần tiêu đề “4. Java chỉ hỗ trợ đơn kế thừa (single inheritance)”

⚠️ Một lớp trong Java chỉ được extends đúng một lớp cha (không như C++ hỗ trợ đa kế thừa nhiều class). Muốn “kế thừa” hành vi từ nhiều nguồn, dùng interface (xem trang “Interface và Abstract class”).

// public class Dog extends Animal, Pet {} // LỖI BIÊN DỊCH! Không thể extends 2 class

Nếu một class không khai báo extends lớp nào, nó ngầm định kế thừa từ lớp Object - lớp gốc của mọi class trong Java, cung cấp sẵn các phương thức như toString(), equals(), hashCode() (xem trang “equals, hashCode và toString”).

  • extends để một lớp con kế thừa thuộc tính và phương thức từ lớp cha
  • super(...) gọi constructor lớp cha; super.method() gọi lại phương thức gốc của lớp cha
  • @Override để ghi đè phương thức của lớp cha với cùng chữ ký
  • Java chỉ hỗ trợ đơn kế thừa giữa các class - dùng interface để có hành vi từ nhiều nguồn