Flight f = new CargoFlight();
khai báo kiểu này cho phép bạn tạo 1 mảng gồm cả Flight và CargoFlight, nếu ko khai báo kiểu này được thì làm sao bạn tạo 1 mảng bao gồm ví dụ [Flight, CargoFlight, Flight]? Kiểu của mảng đó là gì? Flight_CargoFlight[3] arr??
nhờ kế thừa, object của class con có thể được xem như là object của class cha, nên bạn có thể tạo mảng Flight[3] arr rồi gán Flight, CargoFlight, Flight vào arr. Mảng arr lúc này chứa 3 đối tượng, 3 đối tượng này có kiểu là 2 class khác nhau (Flight và CargoFlight)
công dụng gộp chung object của các class khác nhau vào 1 mảng này chỉ là 1 cộng dụng nhỏ.
kế thừa chả có nghĩa lý gì cả ngoại trừ đỡ mất công copy paste code, đa hình mới làm cho nó có ý nghĩa. Mặc dù arr[0], arr[1], arr[2] đều là kiểu Flight, nhưng ví dụ gọi arr[i].getTypeName() thi với i = 0, 2 nó trả về “flight”, còn i = 1 nó trả về “cargo flight”. 3 object cùng 1 kiểu nhưng khi gọi cùng phương thức nó hành động khác nhau. Điều này rất có ích khi bạn muốn viết code mà ko cần chỉnh sửa vẫn có thể mở rộng nó ra được. Ví dụ nếu bạn có 1 class khác có 1 phương thức check in cho các chuyến bay:
// Boarding.java
public void checkIn(Flight f)
{
f.checkA();
f.checkB();
}
nếu ko có đa hình, để check in các chuyến bay f có kiểu là Flight thì ko có vấn đề gì, nhưng nếu f có kiểu là CargoFlight thì bây giờ bạn phải viết thêm 1 phương thức mới
public void checkIn(CargoFlight f)
{
f.check1();
f.check2();
}
điều này rất bất tiện, mỗi khi có kiểu bay mới bạn lại phải vào Boarding.java thêm sửa phương thức, phải compile lại Boarding từ đầu, mất thời gian.
thay vào đó, nhờ đa hình mà CargoFlight có thể được xem như là Flight, và mặc dù code checkIn 2 kiểu khác nhau, bạn có thể tạo phương thức mới chung cho 2 kiểu, ví dụ là check()
// trong class Flight
public void check()
{
checkA();
checkB();
}
// trong class CargoFlight
public void check()
{
check1();
check2();
}
// trong class Boarding
public void checkIn(Flight f) //f có thể là Flight hay CargoFlight
{
f.check();
}
//...
Flight f1 = new Flight();
CargoFlight f2 = new CargoFlight();
Flight f3 = new CargoFlight(); //f3 là kiểu CargoFlight nhưng được xem là Flight
boarding.checkIn(f1); //gọi checkA checkB
boarding.checkIn(f2); //gọi check1 check2
boarding.checkIn(f3); //gọi check1 check2
tùy vào f là kiểu Flight hay CargoFlight, nó sẽ gọi đúng phương thức check1() check2() hay checkA() checkB(). Mặc dù f3 được xem như là kiểu Flight, ko có check1 check2 nhưng vãn gọi được 2 phương thức này thông qua check(), nhờ có đa hình gọi đúng phương thức check của CargoFlight thay vì check của Flight. Như vậy class Boarding chỉ cần viết 1 lần rồi ko chỉnh sửa nó nữa, mỗi lần cần thêm kiểu bay mới chỉ cần kế thừa Flight và override phương thức check() là Boarding sẽ nhận checkIn() cho kiểu bay mới đó.