Chào các bạn đã đến với chủ đề tiếp theo của mình. Hôm nay, mình sẽ tiếp tục tìm hiểu về cách Ghi đè phương thức (overriding method) trong lập trình Java. Ở bài này, mình sẽ đi qua những nội dung như sau:
Nội dung
1. Ghi đè phương thức (method overriding) trong Java là gì?
Trong những bài hướng dẫn trước, chúng ta đã tìm hiểu về tính kế thừa. Tính kế thừa là một thuộc tính của lập trình hướng đối tượng cho phép chúng ta kế thừa một class mới (subclass) từ một class đang tồn tại.
Bây giờ, nếu một phương thức cùng được định nghĩa trong cả superclass và subclass, thì phương thức trong subclass sẽ ghi đè lên phương thức trong superclass. Đây được gọi là ghi đè phương thức(Method Overriding).
2. Ví dụ về ghi đè phương thức trong Java
Chũng ta hãy xem ví dụ bên dưới:
class Animal {
public void displayInfo() {
System.out.println("I am an animal.");
}
}
class Dog extends Animal {
@Override
public void displayInfo() {
System.out.println("I am a dog.");
}
}
class Main {
public static void main(String[] args) {
Dog d1 = new Dog();
d1.displayInfo();
}
}
Khi chạy chương trình, kết quả sẽ là:
I am a dog.
Trong chương trình ở trên, phương thức displayInfo() xuất hiện trong cả superclass Animal và subclass Dog.
Khi chúng ta gọi phương thức displayInfo() sử dụng đối tượng d1 (đối tượng của subclass, phương thức bên trong subclass dog sẽ được gọi. Phương thức displayInfo() của subclass sẽ ghi đè lên phương thức giống nó trong superclass.
Lưu ý việc sử dụng thẻ @override trong ví dụ trên. Trong Java, các thẻ annotation là các metadata chúng ta sử dụng để cung cấp thêm thông tin cho trình biên dịch. Ở đây, thẻ @override chỉ định trình biên dịch rằng phương thức đằng sau thẻ này sẽ ghi đè phương thức của superclass.
Chương trình không bắt buộc sử dụng annotation @Override
. Nhưng khi đã sử dụng thì phải tuân thủ các quy tắc overriding nếu không trình biên dịch sẽ báo lỗi.
3. Các quy tắc ghi đè (overriding)
- Cả lớp cha và lớp con phải có cùng tên phương thức, cùng kiểu trả về và cùng danh sách tham số.
- Chúng ta không thể ghi đè phương thức được khai báo là final và static.
- Lớp con phải luôn luôn ghi đè (overriding) phương thức trừu tượng của lớp cha
4. Sử dụng từ khóa super với overriding trong Java
Chúng ta có thể gọi phương thức của lớp cha trong lớp con sau khi đã ghi đè (overriding) phương thức đó bằng cách sử dụng từ khóa super.
class Animal {
public void displayInfo() {
System.out.println("I am an animal.");
}
}
class Dog extends Animal {
public void displayInfo() {
super.displayInfo();
System.out.println("I am a dog.");
}
}
class Main {
public static void main(String[] args) {
Dog d1 = new Dog();
d1.displayInfo();
}
}
Khi chạy chương trình, kết quả sẽ là:
I am an animal.
I am a dog.
Trong ví dụ trên, subclass dog ghi đè lên phương thức displayInfo() của superclass Animal.
Khi ta gọi phương thức displayInfo() sử dụng đối tượng d1 của subclass dog, phương thức bên trong subclass Dog được gọi còn phương thức bên trong superclass không được gọi. Chúng ta đã sử dụng super.displayInfo() để gọi phương thức displayInfo() của superclass bên trong phương thức displayInfo() của subclass Dog.
Điều quan trọng phải lưu ý là các hàm tạo trong Java sẽ không được kế thừa. Do đó, không có gì gọi là ghi đè hàm tạo trong Java cả.
Tuy nhiên, chúng ta có thể gọi hàm tạo của superclass từ subclass của nó. Khi đó ta sử dụng super(). Để tìm hiểu thêm, hãy tham khảo từ khóa super trong Java.
5. Access modifier với ghi đè phương thức
Phương thức cùng được khai báo trong superclass và subclass có thể có các access specifier khác nhau. Tuy nhiên, điều này cũng có giới hạn.
Chúng ta chỉ có thể sử dụng các access specifier trong subclass mà cung cấp quyền truy cập rộng hơn access specifier của superclass. Lấy ví dụ,
Giả sử, một phương thức là myClass() trong superclass được khai báo là kiểu protected, thì phương thức cùng tên trong subclass có thể là public hoặc protected, nhưng không thể là private.
class Animal {
protected void displayInfo() {
System.out.println("I am an animal.");
}
}
class Dog extends Animal {
public void displayInfo() {
System.out.println("I am a dog.");
}
}
class Main {
public static void main(String[] args) {
Dog d1 = new Dog();
d1.displayInfo();
}
}
Khi chạy chương trình, kết quả sẽ là:
I am a dog.
Trong ví dụ trên, subclass Dog ghi đè phương thức displayInfo() của superclass Animal.
Bất cứ khi nào chúng ta gọi phương thức displayInfo() sử dụng đối tượng d1 (đối tượng của subclass), phương thức bên trong subclass được gọi.
Lưu ý rằng, phương thức displayInfo() được khai báo là protected trong superclass animal. Phương thức tương tự lại có access specifier là public trong subclass Dog. Điều này hoàn toàn có thể bởi vì access specifier public cung cấp quyền truy cập rộng hơn so với access specifier protected.
6. Ghi đè các phương thức trừu tượng
Trong Java, các class trừu tượng được tạo ra để làm superclass cho các class khác. Và nếu một class chứa một phương thức trừu tượng, việc ghi đè nó là điều bắt buộc.
Các bạn có thể xem lại chủ đề Lớp và phương thức trừu tượng ở những bài trước nhé.
7. Kết
Như vậy chúng ta đã tìm hiểu xong về cách Ghi đè phương thức (overriding method)trong lập trình Java. Cảm ơn các bạn đã theo dõi bài viết của mình. Chúc các bạn thành công. Hẹn gặp lại các bạn ở những chủ đề tiếp theo.
Nguồn:
https://cafedev.vn/tu-hoc-java-ghi-deoverriding-phuong-thuc-trong-java/