Tính kế thừa trong Java là một trong những khái niệm quan trọng khi lập trình và tìm hiểu về ngôn ngữ này. Do vậy, trong bài viết này, chúng ta sẽ cùng tìm hiểu về tính kế thừa trong Java và các kiểu kế thừa cùng với sự trợ giúp của ví dụ dẫn chứng.
Kế thừa
Kế thừa là một trong những tính năng chính của lập trình hướng đối tượng (OOP) cho phép chúng ta tạo một lớp mới từ một lớp hiện có. Lớp mới được tạo ra được gọi là lớp con, hoặc lớp dẫn xuất và lớp hiện có từ nơi lớp con được dẫn xuất được gọi là lớp cha, hoặc còn gọi là lớp cơ sở. Từ khóa extends được sử dụng để thực hiện kế thừa trong Java.
Ví dụ:
class sinh_vien { public void in_thong_tin(){ System.out.println("Day la sinh vien"); } } class sinh_vien_truong_y extends sinh_vien { } class Main { public static void main(String[] args) { sinh_vien_truong_y sv = new sinh_vien_truong_y(); sv.in_thong_tin(); } }
Kết quả:
Day la sinh vien
Ví dụ 2:
class sinh_vien { int ID_sv; public void in_thong_tin(){ System.out.println("Day la sinh vien"); } } class sinh_vien_truong_y extends sinh_vien { public void in_thong_tin(){ System.out.println("Day la sinh vien truong y"); } } class Main { public static void main(String[] args) { sinh_vien_truong_y sv = new sinh_vien_truong_y(); sv.ID_sv = 2; sv.in_thong_tin(); System.out.println("Ma so ID la: " + sv.ID_sv); } }
Kết quả:
Day la sinh vien truong y Ma so ID la: 2
Trong đoạn mã trên, ta đã thực hiện một lớp sinh_vien_truong_y kế thừa từ lớp sinh_vien. Ngoài ra, vì lớp sinh_vien_truong_y kế thừa từ lớp sinh_vien, nên ta có thể truy cập dữ liệu thành viên của lớp sinh_vien từ một đối tượng sv của lớp sinh_vien_truong_y.
Mối quan hệ “là”
Trong Java, kế thừa là một mối quan hệ “là”. Có nghĩa là, chúng ta chỉ sử dụng tính kế thừa nếu tồn tại một mối quan hệ “là” giữa hai lớp.
Ví dụ:
- Chiếc ô tô là một phương tiện.
- Con vịt là một con vật.
Như vậy, ô tô là một lớp kế thừa từ lớp phương tiện và con vịt sẽ kế thừa từ lớp con vật.
Ghi đè phương thức trong việc kế thừa
Trong ví dụ 1, chúng ta thấy đối tượng của lớp con có thể truy cập vào phương thức của lớp cha. Tuy nhiên, nếu cùng một phương thức xuất hiện trong cả lớp cha và lớp con, điều gì sẽ xảy ra?
Trong trường hợp này, phương thức trong lớp con sẽ ghi đè phương thức trong lớp cha. Khái niệm này được gọi là ghi đè phương thức trong Java.
Ví dụ:
class sinh_vien { int ID_sv; public void in_thong_tin(){ System.out.println("Day la sinh vien"); } } class sinh_vien_truong_y extends sinh_vien { @Override public void in_thong_tin(){ System.out.println("Day la sinh vien truong y"); } } class Main { public static void main(String[] args) { sinh_vien_truong_y sv = new sinh_vien_truong_y(); sv.ID_sv = 2; sv.in_thong_tin(); System.out.println("Ma so ID la: " + sv.ID_sv); } }
Kết quả:
Day la sinh vien truong y Ma so ID la: 2
Trong đoạn mã trên, phương thức in_thong_tin() của lớp sinh_vien_truong_y đã ghi đè phương thức với cùng tên trong lớp cha là sinh_vien.
Chú ý: Chúng ta đã sử dụng @Override để thông báo cho trình biên dịch biết rằng chúng ta đang ghi đè một phương thức. Tuy nhiên, chú thích này là không bắt buộc.
Từ khóa supter trong việc kế thừa
Chúng ta đã thấy rằng một phương thức cùng tên trong lớp con sẽ ghi đè phương thức cũng cùng tên trong lớp cha. Trong tình huống như vậy, từ khóa super sẽ được sử dụng để gọi phương thức của lớp cha từ phương thức của lớp con.
Ví dụ:
class sinh_vien { int ID_sv; public void in_thong_tin(){ System.out.println("Day la sinh vien"); } } class sinh_vien_truong_y extends sinh_vien { @Override public void in_thong_tin(){ super.in_thong_tin(); System.out.println("Day la sinh vien truong y"); } } class Main { public static void main(String[] args) { sinh_vien_truong_y sv = new sinh_vien_truong_y(); sv.ID_sv = 2; sv.in_thong_tin(); System.out.println("Ma so ID la: " + sv.ID_sv); } }
Kết quả:
Day la sinh vien Day la sinh vien truong y Ma so ID la: 2
Trong đoạn mã trên, cả lớp con và lớp cha đều có cùng phương thức in_thong_tin(), tuy nhiên ta đã sử dụng từ khóa super để gọi phương thức của lớp cha trong phương thức của lớp con.
Chú ý: Chúng ta cũng có thể sử dụng từ khóa super để gọi hàm tạo của lớp cha từ hàm tạo của lớp con.
Thành viên protected trong việc kế thừa
Trong Java, nếu một lớp bao gồm các trường và phương thức được khai báo là protected, thì các trường và phương thức này có thể truy cập được từ lớp con của lớp đó.
Ví dụ:
class sinh_vien { int ID_sv; protected void in_thong_tin(){ System.out.println("Day la sinh vien"); } } class sinh_vien_truong_y extends sinh_vien { } class Main { public static void main(String[] args) { sinh_vien_truong_y sv = new sinh_vien_truong_y(); sv.ID_sv = 2; sv.in_thong_tin(); System.out.println("Ma so ID la: " + sv.ID_sv); } }
Kết quả:
Day la sinh vien Ma so ID la: 2
Tại sao phải sử dụng kế thừa?
- Việc sử dụng kế thừa được coi là quan trọng nhất trong Java là khả năng tái sử dụng đoạn mã. Đoạn mã có trong lớp cha có thể được sử dụng trực tiếp bởi lớp con.
- Ghi đè phương thức còn được gọi là tính đa hình trong thời gian chạy. Do đó, chúng ta có thể đạt được tính đa hình trong Java với sự trợ giúp của tính kế thừa.
Các kiểu kế thừa
Có năm loại thừa kế.
1. Thừa kế đơn
Trong thừa kế đơn, một lớp con duy nhất kế thừa từ một lớp cha duy nhất.
Ví dụ:
2. Kế thừa đa cấp
Trong kế thừa đa cấp, một lớp con kế thừa từ một lớp cha và sau đó lớp con đó có chức năng sẽ là một lớp cha cho một lớp khác.
Ví dụ:
3. Kế thừa phân cấp
Trong kế thừa phân cấp, nhiều lớp con sẽ có thể kế thừa từ một lớp cha duy nhất.
Ví dụ:
4. Đa kế thừa
Trong đa kế thừa, một lớp con duy nhất có thể kế thừa từ nhiều lớp cha.
Ví dụ:
5. Kế thừa kết hợp
Kế thừa kết hợp là sự kết hợp của hai hay nhiều kiểu thừa kế.
Ví dụ:
Ở đây, chúng ta đã kết hợp kế thừa phân cấp và đa kế thừa để tạo thành kế thừa kết hợp.
Trên đây là khái niệm và ví dụ cơ bản về tính kế thừa trong Java. Hy vọng mọi người có thể áp dụng vào trong chương trình của mình. Mọi người hãy tiếp tục theo dõi các bài tiếp theo và cập nhật các bài mới nhất trên tek4 nhé!
P/s: Cảm ơn mọi người!