• Nếu một phương thức có cùng đặc tính trong cả hai khai báo ở lớp cơ sở và lớp thừa hưởng nhưng các phương thức này thì không khai báo virtual hay overriden thì sẽ được gọi là: "lớp
Trang 1NHỮNG KHÁI NIỆM CƠ BẢN CỦA LẬP TRÌNH HƯỚNG ĐỐI
TƯỢNG
Khái niệm:
Lập trình hướng đối tượng gọi tắt là OOP (Object-Oriented Programming) là kĩ
thuật hỗ trợ công nghệ đối tượng OOP được xem là ngôn ngữ lập trình giúp tăng năng suất lập trình, giúp đơn giản hóa việc lập trình và mở rộng chức
năng lập trình, giúp dễ dàng bảo trì và mở rộng các chức năng phần mềm
bằng các cho phép lập trình viên có thể tương tác với các đối tượng phần mêm
ở mức cao hơn Phương pháp lập trình hướng đối tượng còn được xem là dễ tiếp thu hơn là những phương pháp trước đó
(Một sự hiểu đơn giản là đây là phương pháp giúp giảm nhẹ cho việc lập trình, giúp cho người lập trình tạo ra những đối tượng mà cho phép các đội tượng bên ngoài tương tác lên nó như tương
tác tới một đối tượng vật lý.)
(Trên là cái hiểu nôm na của mình về hướng đối tượng Cái đặc biệt của hướng đối tượng là các tính chất của nó, khi hiểu rõ các tính chất của hướng đối tượng sẽ giúp bạn bước vào sử dụng nó linh động hơn.)
Trang 2MỘT SỐ KHÁI NIỆM VỀ HƯỚNG ĐỐI TƯỢNG
• Cú pháp thừa kế trong C#, các chức năng ảo, và các tính năng liên quan
• Những phương thức nạp chồng: C# cho phép bạn định nghĩa những dạng khác nhau của một phương thức trong một lớp Trình biên dịch sẽ tự động chọn phương thức nào thích hợp nhất dựa vào tham số truyền vào của nó
• Construction và Destruction: Nó chỉ rõ cách mà một đối tượng khởi tạo sẽ
có một số hành động tự động kèm theo và tự động giải phóng khi kết thúc
• Struct: là những kiểu giá trị mà cung cấp những tiện nghi khi bạn cần một số tính năng của một lớp mà không cần phải vất vả tạo ra một thực thể lớp cho phức tạp
• Nạp chồng toán hạng : sẽ kiểm tra cách để định nghĩa những toán hạng cho lớp của bạn
• Indexers: Cho phép một lớp được xử lý chỉ mục khi nó là một mảng và có thể đơn giản hoá cách sử dụng những lớp chứa các tập đối tượng
• Giao diện : C# hỗ trợ thừa kế giao diện tốt như thừa kế thực thi, bạn sẽ
được biết rõ hơn ở phần sau
Trang 3• myObject = new MyClass();
//Tuy nhiên bạn có thể khai báo và khởi tạo đối tượng cùng một lúc
• MyClass myObject = new MyClass();
-Các lớp bao gồm nhiều thành viên, mỗi thành viên là thuật
ngữ(term) dùng để chỉ đến một dữ liệu hay một chức năng nào
đó được định nghĩa trong lớp đó Ví dụ chúng ta dùng thuật
ngữ Function để chỉ những thành viên chứa mã như các
phương thức(methods), các thuộc tính(properties), constructor, hay các nạp chồng toán hạng(Operator Overloads).
Trang 4• C# hỗ trợ đơn thừa kế giữa các lớp Một lớp có thể thừa hưởng những
thuộc tính và phương thức từ một lớp khác
• Cú pháp này khác với C++ về phạm vi, không có bổ từ truy cập(access
modifier) Tức là C# không hỗ trợ như C++ về các khái niệm thừa kế public hay private vì nó làm ngôn ngữ thêm phức tạp (thừa kế private rất ít được
sử dụng).
Trong C# một lớp bắt buột phải thừa kế từ một lớp nào đó C# hỗ trợ một lớp
cơ sở toàn diện gọi là System.Object.
Trang 5Phương thức nạp chồng(Overloading)
• C# hỗ trợ phương thức nạp chồng với một vài dạng phương thức khác nhau
về những đặc tính sau: tên, số lượng thông số, và kiểu thông số Nhưng nó không hỗ trợ những thông số mặc định như C++ và VB Một cách đơn giản là bạn khai báo những phương thức cùng tên nhưng khác số lượng và kiểu của thông số:
Trang 6Phương thức nạp chồng(Overloading)
• Bởi vì C# không hỗ trợ những thông số tuỳ chọn nên bạn cần sử dụng
những phương thức nạp chồng để đạt được cùng một hiệu quả:
-Nó không chấp nhận hai phương thức chỉ khác nhau về kiểu trả về
-Nó không chấp nhận hai phương thức chỉ khác nhau về đặc tính của một thông số đang được khai
báo như ref hay out
Trang 7-Bằng cách khai báo virtual trong một hàm ở lớp cơ sở thì cho phép hàm đó được overriden trong bất
kỳ một lớp thừa hưởng nào.
phương thức của lớp thừa hưởng sẽ được thi hành mà không quan tâm đến phương thức đó ở
lớp cơ sở Khác với C++ và Java, trong C# những hàm không được khai báo virtual mặc định mà bạn phải khai báo virtual một cách rõ ràng và khi một hàm muốn override một hàm khác thì phải
Trang 8• Nếu một phương thức có cùng đặc tính trong cả hai khai báo ở lớp cơ sở và lớp thừa hưởng nhưng các phương thức này thì
không khai báo virtual hay overriden thì sẽ được gọi là: "lớp
thừa hưởng hide lớp cơ sở đó" Kết quả là: phương thức nào
được gọi phụ thuộc vào kiểu của biến được sử dụng để tham khảo đến thể hiện, chứ không phải kiểu của chính thể hiện đó.
• Nếu bạn tạo ra hai phương thức hoàn toàn giống nhau ở cả lớp
thừa hưởng và lớp cơ sở mà không có khai báo virtual và
override thì bạn sẽ bị cảnh báo trong khi biên dịch Trong C#,
bạn nên sử dụng từ khoá new để đảm bảo bạn muốn hide
phương thức đó
Trang 10-C# cho phép cả lớp và phương thức có thể khai báo abstract
Một lớp abstract không được thể hiện và một phương thức
abstract không được thực thi mà phải được overriden trong bất
kỳ lớp thừa hưởng không abstract nào Một phương thức
abstract sẽ tự động được khai báo virtual Nếu một lớp có
phương thức abstract thì nó cũng là lớp abstract và được khai báo như sau:
abstract class Building
{
public abstract decimal CalculateHeatingCost(); // phương pháp trừu tượng
}
Trang 11• C# cho phép các lớp và phương thức được khai báo sealed Nếu là lớp có
nghĩa là bạn không được quyền thừa kế lớp đó, nếu là phương thức tức là bạn không được phép override nó
• C# sử dụng từ khoá sealed trước tên lớp và phương thức
Trang 12• Thủ tục get không có tham số và phải trả về cùng kiểu với thuộc tính đã
được khai báo
private string foreName;
public string ForeName
Khác với VB các thủ tục get và set được định nghĩa như là những hàm riêng biệt, trong C# chúng được khai báo
cùng nhau trong một khai báo thuộc tính đơn.Trong VB bạn khai báo tường minh tham số cho thủ tục set và
có thể chọn tên của nó, nhưng ngược lại trong C# tham số này hoàn toàn giả lập và luôn mang tên là value.
Trang 13C# không cho phép cài đặt những bổ từ khác nhau cho thủ tục set và get Nếu
bạn muốn tạo ra một thuộc tính có public để đọc nhưng lại muốn hạn chế protected trong gán thì đầu tiên bạn phải tạo thuộc tính chỉ đọc với bổ từ
public sau đó tạo một hàm set() với bổ từ protected ở bên ngoài thuộc tính
Trang 14C# cho phép bạn tạo một thuộc tính virtual hay abstract Để khai báo một thuộc tính virtual,
overriden hay abstract bạn chỉ cần thêm từ
khoá đó trong lúc định nghĩa thuộc tính Ví dụ
để tạo một thuộc tính abstract thì cú pháp như sau:
public abstract string ForeName
{
get;
set;
}
Trang 15Lớp đối tượng
Trang 16- C# hỗ trợ giao diện (Interfaces) Khi thừa kế một giao diện, một lớp đang khai báo sẽ thực thi những hàm nào đó Chúng ta sẽ minh họa về giao diện thông qua việc giới thiệu một giao diện
đã được Microsoft định nghĩa, System.IDisposable IDisposable chứa một phương thức Dispose() dùng để xoá mã.
public interface Idisposable
Trang 17/ / Phần còn lại của định nghĩa lớp
• Như trong c++ và java, bạn có thể không cần định nghĩa constructor trong lớp của bạn nếu không cần thiết Nếu bạn không định nghĩa một constructor nào trong lớp của bạn thì trình biên dịch tạo một constructor mặc định để khởi tạo một số giá trị mặc định như: gán chuỗi rỗng cho chuỗi, gán 0 cho kiểu số, false cho kiểu bool
Chú ý :+ khi bạn đã định nghĩa một constructor trong lớp của bạn thì trình biên dịch sẽ không tự động tạo ra constructor mặc định
+Nếu bạn định nghĩa một hay nhiều constructor private thì những lớp thừa
kế lớp của bạn sẽ không thể khởi tạo được Do đó chúng ta phải cân nhắc
kỹ lưỡng khi định nghĩa bổ từ của một constructor
Trang 18- Một nguyên nhân để viết một constructor tĩnh là: Nếu lớp của bạn có một
số trường hay thuộc tính cần được khởi tạo từ bên ngoài trước khi lớp
được sử dụng lần đầu tiên
- Trong C#, Constructor tĩnh thường được thực hiện ngay trước lần gọi đầu tiên của một thành viên trong lớp đó
-có thể Gọi các constructor từ những constructor khác
Trang 19-C# cũng hỗ trợ Destructor, nhưng chúng không được dùng thường xuyên như trong C++ và cách chúng hoạt động rất khác nhau Bởi vì các đối tượng trong NET và C# thì bị xoá bởi bộ thu gom rác (garbage collection) Trong C#, mẫu destruction làm việc theo hai giai đoạn:
1.Lớp sẽ thực thi giao diện System.IDisposable, tức là thực thi phương thức
IDisposable.Dispose() Phương thức này được gọi tường minh khi trong đoạn mã khi một đối
tượng không cần nữa
2 Một Destructor có thể được định nghĩa và nó được tự động gọi khi đối tượng bị thu gom rác Destructor chỉ đóng vai trò như một máy rà soát lại trong một số trường hợp xấu client không
gọi phương thức Dispose().
Cú pháp của một Destructor giống như một phương thức nhưng có cùng tên với lớp, có tiền tố là một dấu sóng(~), không có kiểu trả về, không có tham số truyền và không có bổ từ
Trang 202 Bạn có thể tác động đến bộ thu gom rác để chạy tại một thời điểm trong đoạn mã của
bạn bằng cách gọi phương thức System.GC.Collect() System.GC là một lớp cơ
sở NET mô tả bộ thu gom rác và phương thức Collect() dùng để gọi bộ thu gom rác.
3 Có một lời khuyên là chúng ta không nên thực thi một Destructor nếu như lớp của bạn không thực sự cần đến nó Nếu một đối tượng thực thi một Destructor, thì nó đặt một đặc tính quan trọng vào quá trình thu gom rác của đối tượng đó Nó sẽ trì hoãn việc di chuyển cuối cùng của đối tượng từ bộ nhớ Những đối tượng không có một Destructor thì bị xoá khỏi bộ nhớ trong một lần hoạt động của bộ thu gom rác Còn đối tượng có Destructor thì nó sẽ qua hai bước : lần đầu nó gọi Destructor mà không xoá đối tượng, lần thứ hai mới thực sự xoá đối tượng.
-Chú ý : Không có bất kỳ một tham số nào trong một Destructor, không kiểu trả về và không có bổ từ Không cần thiết phải gọi tường minh một Destructor của lớp cơ sở
mà trình biên dịch sẽ tự động sắp xếp tất cả Destructor được định nghĩa trong các lớp thừa kế đều được gọi
Trang 21- Hằng là một biến mà chứa một giá trị không thay đổi Trong C# khái niệm hằng cũng giống như mọi ngôn ngữ khác C# hỗ trợ một kiểu biến khác có lợi hơn trong trường hợp này là: các trường chỉ đọc
- Từ khoá readonly thì linh động hơn từ khoá const.
-Bởi vì bạn có thể khởi tạo giá trị cho một trường chỉ đọc trong constructor
Và nó cho phép một trường chỉ đọc là một thể hiện(instance) hay một
trường static có các giá trị khác nhau trong mỗi thể hiện của lớp đó Nếu
bạn muốn một trường chỉ đọc là static thì bạn phải khai báo tường minhChú ý: trường chỉ đọc và nó không thể được gán giá trị bên ngoài constructor
Trang 22-Cú pháp để định nghĩa một struct được mô tả trong ví dụ sau:
struct Dimensions
{
public double Length;
public double Width;
}
1.Struct là một kiểu giá trị, không phải là kiểu tham khảo
2 Struct không hổ trợ thừa kế.
3 Có vài sự khác nhau trong cách làm việc của các constructor đối với struct Trình biên dịch luôn luôn cung cấp một constructor không tham số mặc định, và không được cho phép thay thế.
4 Với một struct, bạn có thể chỉ rỏ cách mà các trường được đặt ngoài bộ nhớ
- Mặc dù struct là kiểu giá trị nhưng cú pháp để sử dụng nó giống như sử dụng lớp Ví dụ như bạn khai báo như trên thì bạn có thể viết như sau:
Dimensions point = new Dimensions();
point.Length = 3;
point.Width = 6;
Chú ý rằng struct là các kiểu giá trị, do đó thao tác new sẽ không làm việc theo cách của lớp hay
những kiểu tham khảo khác Nó chỉ đơn giản định vị trên bộ nhớ và gọi constructor thích hợp
để khởi tạo các trường Do đó bạn hoàn toàn có thể viết:
Trang 23-Một số trường hợp chúng ta nên viết các toán hạng nạp chồng:
1 Trong thế giới toán học, mọi đối tượng toán học như: tọa độ, vector, ma trận, hàm số và vân vân Nếu bạn viết chương trình làm những mô hình toán học hay vật lý, bạn nhất định sẽ mô tả những đối tượng này.
2.Những chương trình đồ hoạ sẽ sử dụng các đối tượng toán học và toạ độ khi tính toán vị trí của trên màn hình.
3 Một lớp mô tả số lượng tiền.
4 Việc sử lý từ hay chương trình phân tích văn bản có lớp để mô tả các câu văn, mệnh đề và bạn phải sử dụng các toán hạng để liên kết các câu lại với nhau.
Trang 25ĐÓNG GÓI
Đóng gói trong class, giúp phân biệt giữa các đối tượng khác nhau, giúp tái sử dụng trong 1 chương trình khác
Trang 26Chúng ta đã kiểm tra một số tính năng của C# để viết mã và các lớp dễ
dàng hơn, cho phép chúng có nhiều cú pháp trực quan hơn Chúng ta thấy được cách mà C# quản lý bộ nhớ của nó Nó sẽ rất có lợi khi bạn viết các chương trình lớn Chúng ta kiểm tra cách mà các construcotr và Destructor khởi tạo cho các đối tượng, cách chúng hoạt động và bị xoá tài nguyên khi đối tượng bị hủy Chúng ta thấy được sự cải tiến khi định nghĩa struct thay cho lớp Và chúng ta biết được một vài cú pháp tiện lợi khi nó cung cấp những toán hạng nạp chồng, indexer, và phương thức nạp chồng