December 2016


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!



Chào các bạn,



Đã lâu rồi mình không viết blog, phần vì cũng lười, phần vì vừa phải làm final project tại CoderSchool. Hôm nay vừa internal demo xong, mình ngồi refactor lại code thì thấy như sau


Nhìn vào đống item ở thư mục 'res/layout' kìa!
Horrible, right?

Lang thang search trên mạng cũng thấy nhiều người có vấn đề giống như mình, như article ở StackOverflow.

Thư mục 'res/layout' của bạn quá lớn? khó kiểm soát? khó tìm kiếm? Hãy tưởng tượng trong lúc đang chạy deadline đầu óc rối bời mà tìm hoài không thấy cái 'item_recently_search.xml' nằm ở đâu? (mình cũng vừa bị T.T)

Ok, dài dòng đủ rồi, mình sẽ hướng dẫn các bạn ngay đây.

Bước 1: Đầu tiên các bạn tạo folder tổng "layouts"
Right-click vào thư mục 'res' -> New -> Directory -> gõ "layouts" (nhớ là có 's' nhé, không là bị trùng đấy)



Bước 2: Tạo các Res Folder tương ứng với các category mà bạn muốn làm.
Chọn 'layouts' folder vừa tạo.
Right-click -> New -> Folder -> Res Folder



Đặt tên cho Res Folder theo category mà bạn muốn làm.
Ví dụ ở một chương trình chat bạn sẽ có các category là "home", "profile" và "chat". Ví dụ mình sẽ đặt tên nó là 'chat' nha.

Khi vừa add xong 1 folder, đợi 1 lát để Gradle update cấu trúc chương trình. Sau đó bạn sẽ thấy một folder 'char' màu vàng tương ứng với folder 'res' nhưng lại không năm trong folder 'layouts'.
Thực chất nó vẫn nằm trong 'layouts' tuy nhiên vì minh chỉ mới add một folder duy nhất là 'chat' nên nó chỉ show 'chat' ra thôi.

Tiếp tục bạn tạo thêm một Res Folder mới tên là 'home' thì cấu trúc cây sẽ bắt đầu hiện ra đúng theo những gì bạn mong đợi: 'home' và 'chat' nằm trong 'layouts'.

Tới đây bạn đã chia thành công thư mục ra thành các category riêng biệt rồi.

Bước 3: Thêm folder 'layout' (không có 's') vào từng sub-folder tương ứng với các category cần thiết và sử dụng chúng bình thường như folder 'res/layout' truyền thống. 
Bạn cũng có thể thêm các folder 'menu', 'drawable', 'anim',... vào từng Res Folder nha.

Bước 4: Build thử chương trình. Bạn sẽ thấy trong tag 'android' của file 'app/build.gradle' xuất hiện đoạn lệnh sau


Đoạn lệnh này tương ứng cho khi bạn add 2 category là 2 Res Folder 'home' và 'chat'.
Nếu không tìm thấy các bạn có thể thêm bằng tay vào tag 'android' nha.


Chúc các bạn thành công và quản lý tốt source code của mình. Bởi vì lập trình còn là một quá trình tạo ra sản phẩm cùng với team nên code style là rất quan trọng. Và những thứ như vậy thường không được dạy ở trường.


Contact Form

Name

Email *

Message *

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