Hàm dựng (constructor) và tính kế thừa trong C#


Chào các bạn,

Đã lâu rồi mình không viết bài về C# nhỉ :D, hôm nay nhân lúc đang làm đồ án môn Thiết kế phần mềm, cần sử dụng OOPinheritance,.. khá nhiều, mình xin viết một article nho nhỏ về hàm dựng (constructor) trong tính kế thừa của C#.



Theo nguyên tắc, khi khởi tạo đối tượng của lớp con, thì hàm dựng (constructor) của lớp cha sẽ được gọi trước, sau đó mới tới đổi tượng của lớp con.

Ví dụ mình có class Base Child kế thừa từ lớp Base như sau:


Thì khi Run, chương trình sẽ cho kết quả như sau:


Rõ ràng constructor của lớp Base đã được gọi trước! 

Chúng ta có thể kiểm tra các trường hợp khác:
 - Cho lớp Base thành abstract.
 - Sửa lại hàm Main, khởi tạo đối tượng bằng Child c = new Child();

Tất cả đều cho kết quả tương tự.

Chúng ta tiếp tục thử một trường hợp đặc biệt khác, thêm một constructor mới chứa tham số vào class Base Child như sau:


Run chương trình, chúng ta được kết quả sau:


Ở đây bạn thấy, dù chúng ta tạo đối tượng với constructor có tham số, thì constructor cơ bản của lớp Base luôn được gọi.
Bây giờ nếu bạn xóa đi constructor cơ bản (không tham số) của lớp Base và Run chương trình thì sẽ bị lỗi ngay lập tức.


Từ đó ta rút ra các kết luận sau:

Về vấn đề lỗi khi xóa constructor cơ bản của lớp Base: Khi một class được tạo ra, nếu class đó chưa có constructor, Visual C# sẽ tự động generate một constructor mặc định (không tham số) cho chúng ta, vì nếu không làm vậy chúng ta sẽ không thể tạo một object mới thuộc class đó rồi :D. Tuy nhiên nếu bạn tạo thêm một constructor khác có tham số, và xóa constructor mặc định cơ bản đi, thì Visual C# sẽ cho rằng class của bạn đã có thể tự tạo một object mới và sẽ không generate constructor mặc định. Điều đó đồng nghĩa với việc các object được tạo bằng cách gọi "new Base()" sẽ không thể khởi tạo.

Về vấn đề chính về constructor trong kế thừa mình muốn nói là khi bạn khởi tạo một đối tượng lớp con Child, thì C# sẽ automatically gọi constructor mặc định-không tham số của lớp cha Base trước, sau đó mới gọi constructor của lớp con (constructor nào của lớp con thì còn tùy mình new đối tượng với tham số gì :D).


Tại sao lại như vậy?

Theo ý kiến chủ quan của cá nhân mình, thì bạn cứ tưởng tượng lớp con Child là một "cụ thể hóa" của một lớp cha, giống như một chiếc xe, trước khi thành một chiếc xe nó phải qua công đoạn lắp ráp khung xe, thì KhungXe đó chính là lớp cha. Mà để tạo khung xe thì phải dùng constructor của KhungXe, trong đó sẽ gọi các hàm ráp, hàn, bắt ốc,... Sau khi đã xong phần khung xe, ta gọi constructor của XeMay gọi các hàm gắn bánh, gắn yên xe,.. giúp tạo thành một chiếc xe hoàn chỉnh.
Vậy thứ tự gọi thực sự logic và thực tế đúng không nào?

Nếu bạn muốn gọi constructor có tham số cụ thể của lớp cha theo ý của mình thì sử dụng tự khóa "base" như sau:



Trên là một số kiến thức tổng quát về Lập trình hướng đối tượng (OOP) cho các bạn nào lỡ quên :D.
Minh xin nói luôn một cách tổng quát, trong Java thì hàm dựng của lớp cha cũng sẽ tự động được gọi khi khởi tạo đối tượng của lớp con. Các bạn có thể tham khảo tại đây.



Cuối cùng, mình có một câu hỏi cho các bạn, có cách nào để tạo một đối tượng thuộc lớp con mà không cần gọi hàm dựng (constructor) của lớp cha không? 

Chào các bạn, chúc các bạn học tốt!


Post a Comment

[facebook][blogger]

Contact Form

Name

Email *

Message *

Powered by Blogger.
Javascript DisablePlease Enable Javascript To See All Widget