Đa hình
Nội dung bài · 5 mục
- 1.Khái niệm
- 2.Ví dụ
- 3.Thử ngay
- 4.Lỗi hay gặp
- 5.Tóm tắt
Giỏ hàng có sách giấy tính phí ship theo cân nặng và ebook miễn phí ship.
Viết if kiểm tra từng loại thì mỗi lần thêm loại hàng mới lại phải sửa giỏ
hàng. Với đa hình, mỗi loại tự biết cách tính của mình.
Khái niệm
🎭 Đa hình (polymorphism): cùng một lời gọi method, mỗi class con chạy cách làm riêng của nó.
🔧 Override (ghi đè): class con viết lại một method của class cha với cùng tên và cùng tham số, thường đánh dấu bằng @Override.
Ví dụ
// Main.java
void main() {
List<Product> cart = List.of(
new PhysicalProduct("Sách", 800),
new DigitalProduct("Ebook Java"));
for (Product item : cart) {
System.out.println(
item.getName() + ": " + item.shippingFee());
}
}
// Product.java
class Product {
private String name;
public Product(String name) {
this.name = name;
}
public String getName() {
return name;
}
public long shippingFee() {
return 30000;
}
}
// PhysicalProduct.java
class PhysicalProduct extends Product {
private int weightGram;
public PhysicalProduct(String name,
int weightGram) {
super(name);
this.weightGram = weightGram;
}
@Override
public long shippingFee() {
return weightGram * 10;
}
}
// DigitalProduct.java
class DigitalProduct extends Product {
public DigitalProduct(String name) {
super(name);
}
@Override
public long shippingFee() {
return 0;
}
}Sách: 8000
Ebook Java: 0shippingFee()nằm ởProduct. Method thường của class cha đều cho class con override, không cần đánh dấu gì thêm ở class cha.List<Product>chứa được cảPhysicalProductvàDigitalProduct, vì cả hai đều làProduct.- Vòng lặp chỉ gọi
item.shippingFee(), không cần biết món hàng thuộc loại nào. - Java chạy bản override của object thật, không phải bản của
Product. - Thêm loại hàng mới chỉ cần viết class mới có override. Vòng lặp không đổi.
Thử ngay
Giữ các file class của ví dụ, thay main trong Main.java bằng:
// Main.java
void main() {
Product item = new DigitalProduct("Ebook");
System.out.println(item.shippingFee());
Product other = new Product("Quà tặng");
System.out.println(other.shippingFee());
}Đoán trước khi chạy: biến item có kiểu Product. Dòng đầu in 30000
hay 0?
Xem kết quả
0
30000In 0. Kiểu của biến là Product, nhưng object thật là DigitalProduct, và
Java chạy bản override của object thật. Còn other là Product thường nên
chạy bản gốc, in 30000.
Lỗi hay gặp
Bỏ public khi override. Method của class con không được có quyền truy
cập hẹp hơn method của class cha.
// SAI — lỗi compile: fee() hẹp quyền hơn bản của Item
// Main.java
void main() {
new Gift();
}
// Item.java
class Item {
public long fee() {
return 30000;
}
}
// Gift.java
class Gift extends Item {
@Override
long fee() {
return 0;
}
}// ĐÚNG
// Item.java
class Item {
public long fee() {
return 30000;
}
}
// Gift.java
class Gift extends Item {
@Override
public long fee() {
return 0;
}
}Gõ sai tên method và thiếu @Override. Code vẫn compile được vì Java hiểu
đó là một method mới. Gọi qua biến kiểu cha thì chạy bản của cha. Có
@Override thì compiler báo lỗi ngay chỗ gõ sai.
// SAI — fees() là method mới, in ra 30000
// Main.java
void main() {
Item gift = new Gift();
System.out.println(gift.fee());
}
// Gift.java
class Gift extends Item {
public long fees() {
return 0;
}
}// ĐÚNG — có @Override, in ra 0
// Gift.java
class Gift extends Item {
@Override
public long fee() {
return 0;
}
}Tóm tắt
- Đa hình: cùng một lời gọi, mỗi class con chạy cách làm riêng.
- Class con viết lại method của cha với cùng tên, cùng tham số, và đánh dấu
@Overrideđể compiler kiểm tra giúp. - Biến kiểu cha chứa được object của class con, và Java chạy bản của object thật.
- Thêm loại mới chỉ cần thêm class, không sửa nơi gọi.
Tự kiểm tra
0/3 câuclass Animal { public String sound() { return "..."; } } class Dog extends Animal { @Override public String sound() { return "Gâu"; } } Animal a = new Dog(); System.out.println(a.sound()); In ra gì?
Class cha có method public long discount(). Class con viết public long discount() cùng tham số nhưng quên @Override. Chuyện gì xảy ra?
Cửa hàng thêm loại hàng mới là "voucher" với phí ship riêng. Nếu đã dùng đa hình, cần làm gì?