01/10/2018, 17:45

Kế thừa và đa hình trong Java

Chào các anh ạ, em có câu hỏi sau.

Giả sử em có một class Quân Cờ (Em xin phép gõ theo kiểu tiếng Việt cho dễ đọc, dễ hiểu ạ), và class Quân Xe được kế thừa từ Quân Cờ.

2 class trên đều có một method tên là Đi.

Vậy em hiểu như này có đúng không ạ:

Quân Cờ a = new Quân Cờ();
a.Đi;
//Cái này sẽ gọi method đi trong Quân Cờ.

Quân cờ b = new Quân Xe();
b.Đi;
//Cái này sẽ gọi method đi trong Quân Xe.

Vậy cách khai báo Quân cờ b = new Quân Xe(); có tác dụng gì vì nếu b chỉ sử dụng được đi trong Quân Xe thì sao không khai báo luôn là:

Quân Xe b = new Quân Xe(); mà lại dùng cách kia cho phức tạp ạ

Phạm Tiến Đạt viết 19:51 ngày 01/10/2018

Quân cờ b = new Quân Xe ();

Đúng hơn là Quân Xe b = new Quân Cờ();
có 2 cách khai báo biến Quân Xe

  1. Quân Xe b = new Quân Cờ(); ==> vì Quân Xe “ăn bám” Quân Cờ
    Biến b CHỈ CÓ THỂ sử dụng các property, method được khai báo trong Quân Cờ (vì nó được khởi tạo từ Quân Cờ)
  2. Quân Xe b = new Quân Xe(); ==> cái này ai cũng biết
    Biến b CÓ THỂ sử dụng các property, method được khai báo trong Quân Cờ trong Quân Xe vì b được khởi tạo từ Quân Xe nên có các method đã được implement tại Quân Cờ và tại Quân Xe
Ga Mat Ong viết 19:59 ngày 01/10/2018

Anh nhầm ạ, phải là

Quân Cờ b = new Quân Xe(); chứ ạ?

Phạm Tiến Đạt viết 19:45 ngày 01/10/2018

Tại mình hay code như vậy Để chống bug thôi

Quân viết 19:52 ngày 01/10/2018

Hình như có gì đó không đúng ở đây

Nguyễn Đình Anh viết 19:59 ngày 01/10/2018

Vậy cách khai báo Quân cờ b = new Quân Xe (); có tác dụng gì vì nếu b chỉ sử dụng được đi trong Quân Xe thì sao không khai báo luôn là:

Quân Xe b = new Quân Xe(); mà lại dùng cách kia cho phức tạp ạ

Cái này gọi là tính đa hình (Polymorphism) trong OOP. Tác dụng của nó là giúp b được hệ thống coi như là 1 Quân Cờ nhưng nó lại có những tính chất của Quân Xe. Bạn có thể đọc thêm về tác dụng của tính đa hình tại đây:

Có phải bạn thắc mắc như này không ? Ví dụ ta có 1 Class Shape là class cha và 2 Class HinhTamGiac, HinhVuong là class con như sau: public abstract class Shape { public abstract int tinhChuVi(); public abstract void veHinh(); } public class HinhTamGiac extends Shape { @Override public int tinhChuVi() { return 1; // Ở đây chỉ là ví dụ thôi } @Override public void veHinh() { System.out.println("Tam Giac"); } } public class …

Nguyễn Đình Anh viết 19:46 ngày 01/10/2018

Quân Xe b = new Quân Cờ(); ==> vì Quân Xe “ăn bám” Quân Cờ
Biến b CHỈ CÓ THỂ sử dụng các property, method được khai báo trong Quân Cờ (vì nó được khởi tạo từ Quân Cờ)

Bạn có nhầm lẫn ở đâu không. Quân xe có thể được coi là một Quân cờ nhưng mà Quân cờ không thể được coi là 1 Quân xe nhé Nếu bạn khai báo như vậy sẽ có bug ngay nhé Chứ không phải chống bug đâu

Trần Hoàn viết 19:47 ngày 01/10/2018

Đúng hơn là Quân Xe b = new Quân Cờ();
Tại mình hay code như vậy


Quay lại câu hỏi của chủ thớt, nếu như biến b không bị gán lại thì đúng là không cần khai báo như thế, tuy nhiên nếu trong hàm hoặc đối tượng, khi thực hiện công việc nào đó mà người ta muốn gán b = new Quân Mã(); thì làm thế nào?

Vì b có kiểu dữ liệu là Quân Cờ do bạn khai báo ở trên nên nó có thể gán vào lớp con bất kỳ của Quân Cờ, chứ nếu bạn gọi Quân Xe b = new Quân Xe(); từ đầu thì bạn không thể gán b cho một loại quân nào khác ngoài Quân Xe

Và nó cũng giúp cho code của bạn ngắn hơn, có thể cái này không đúng luật cờ vua, nhưng bạn có một việc gì đó muốn nhiều đối tượng cùng làm, hoặc một đối tượng làm nhưng không biết chính xác nó là đối tượng gì, mỗi đối tượng làm một kiểu nhưng công việc này là một hàm có kế thừa:

for (QuanCo a: getAllQuanCo())
	a.Đi();

Như vậy tất cả các quân cờ sẽ đi, dù là mỗi thằng đi 1 kiểu.

rogp10 viết 19:50 ngày 01/10/2018

Vậy cách khai báo Quân cờ b = new Quân Xe (); có tác dụng gì

  1. Trói chặt logic vào class hơn thay vì phải if thì chỉ cần khảo quân cờ “đi tới ô này” là được.
  2. Khi trói như vậy thì bổ sung con mới (hay đổi cách đi) dễ hơn.

Nhưng có cái bàn cờ vẫn tự nhiên hơn.

Bài liên quan
0