Bài giảng tóm tắt Lập trình hướng đối tượng - Trần Thống
Mục lục
Mục lục .1
Mở đầu.3
Chương 1: Kiến trúc .NET .4
1. 1 Quan hệgiữa C# và.NET .4
1. 2 CLR (Common Language Runtime) .4
1. 3 Giới thiệu IL (Intermediate Language) .5
1. 4 Thưviện (Assembly) .5
1. 5 Các lớp trong .NET .5
1. 6 Tạo ứng dụng .NET sửdụng C#.6
1. 7 Vai trò của .NET trong kiến trúc .NET Enterprise.6
Chương 2: Căn bản C# .7
2. 1 Viết chương trình C# đầu tiên .7
2. 2 Biến.11
2. 3 Kiểu dữliệu cơbản.12
2. 4 Điều khiển luồng .14
2. 5 Kiểu liệt kê.19
2. 6 Mảng.21
2. 7 Không gian tên (Namespace) .22
2. 8 Phương thức Main() .23
2. 9 Biên dịch nhiều tập tin C# .23
2. 10 Xuất nhập qua Console.24
2. 11 Sửdụng chú thích .25
2. 12 Chỉdẫn tiền xửlý trong C# .25
Chương 3: Đối tượng và kiểu .27
3. 1 Lớp và cấu trúc .27
3. 2 Thành viên của lớp .29
3. 3 Cấu trúc (Struct) .46
3. 4 Lớp Object.53
Chương 4: Sựkếthừa .56
4. 1 Các kiểu kếthừa .56
4. 3 Từkhóa bổtrợ.59
2
4. 4 Đa hình (polymorphism) .60
Chương 5: Toán tửvà chuyển kiểu.72
5. 1 Toán tử.72
5. 3 Quá tải toán tử.74
5. 4 Chuyển kiểu do người dùng định nghĩa .79
Chương 6: Sự ủy nhiệm, sựkiện và quản lý lỗi.81
6. 1 Sự ủy nhiệm (delegate).81
6. 2 Sựkiện (Event) .82
6. 3 Quản lý lỗi và biệt lệ.85
Chapter 7: Quản lý bộnhớvà con trỏ.89
7. 1 Quản lý bộnhớ.89
7. 2 Giải phóng tài nguyên .90
7. 3 Mã không an toàn .93
Chương 8: Chuỗi, biểu thức quy tắc và tập hợp .97
8. 1 System.String.97
8. 2 Biểu thức quy tắc.98
8. 3 Nhóm các đối tượng .100
Chương 9: Reflection.104
9. 1 Thuộc tính (attribute) tùy chọn.104
9. 2 Reflection.106
Hướng dẫn phần thực hành.110
Tài liệu tham khảo.110
' để lấy dữ liệu. 104 Chương 9: Reflection Mục đích của chương: Sử dụng siêu dữ liệu của .Net. Vai trò của thuộc tính trong quá trình xây dựng ứng dụng. Sử dụng thuộc tính trong quá trình phát triển. Sử dụng reflection để lấy tất cả thông tin về lớp. 9. 1 Thuộc tính (attribute) tùy chọn Viết thuộc tính tuỳ chọn Để hiểu cách viết thuộc tính tùy chọn, ta cần xem trình biên dịch làm gì khi nó gặp một mục trong mã được đánh dấu với một attribute. Giả sử ta có thuộc tính khai báo như sau: [TenTruong("SoCMND")] public string SoCMND { get { // vv... Như ta thấy thuộc tính SoCMND có một thuộc tính TenTruong, trình biên dịch sẽ nối chuỗi attribute với tên này thành TenTruongAttribute, sau đó tìm trong tất cả các namespace lớp có tên này. Tuy nhiên nếu ta đánh dấu một mục với một thuộc tính mà tên của nó có phần cuối là attribute thì trình biên dịch sẽ không thêm chuỗi attribute lần nữa ví dụ: [TenTruongattribute("SoCMND")] public string SoCMND { // vv... Nếu trình biên dịch không tìm thấy một lớp thuộc tính tương ứng, hoặc thấy nhưng cách mà ta dùng thuộc tính không phù hợp với thông tin trong lớp thuộc tính, thì trình biên dịch sẽ sinh ra lỗi. Các lớp thuộc tính tuỳ chọn Giả sử ta đã định nghĩa một thuộc tính TenTruong như sau: [AttributeUsage(AttributeTargets.Property, AllowMultiple=false, Inherited=false)] public class TenTruongAttribute: Attribute { private string ten; public TenTruongAttribute(string ten) { this.ten = ten; } } 105 Điều đầu tiên ta chú ý là lớp attribute được đánh dấu với một thuộc tính “AttributeUsage”. AttributeUsage chỉ định các mục nào trong mã của chúng ta áp dụng thuộc tính tùy chọn. Thông tin này được cho bởi thông số đầu tiên. Thông số này là một kiểu liệt kê attributeTargets. Trong ví dụ trên ta chỉ định thuộc tính TenTruong chỉ được áp dụng đến các thuộc tính. Định nghĩa của kiểu liệt kê attributeTargets là: public enum attributeTargets { All = 0x00003FFF, Assembly = 0x00000001, Class = 0x00000004, Constructor = 0x00000020, Delegate = 0x00001000, Enum = 0x00000010, Event = 0x00000200, Field = 0x00000100, Interface = 0x00000400, Method = 0x00000040, Module = 0x00000002, Parameter = 0x00000800, Property = 0x00000080, ReturnValue = 0x00002000, Struct = 0x00000008 } Khi áp dụng thuộc tính đến các phần tử chương trình, ta đặt thuộc tính trong ngoặc vuông ngay trước phần tử. Một thuộc tính có thể được áp dụng đến một Assembly nhưng cần được đánh dấu với từ khoá Assembly: [assembly: SomeAssemblyattribute(Parameters)] Để kết hợp nhiều kiểu khác nhau trên một phần tử nào đó, ta viết như sau: [attributeUsage(attributeTargets.Property | attributeTargets.Field, AllowMultiple=false, Inherited=false)] public class TenTruongattribute: attribute Ta cũng có thể dùng attributeTargets.All để áp dụng thuộc tính cho tất cả các trường hợp. Thuộc tính attributeUsage còn chứa hai thông số khác là AllowMultiple and Inherited, chỉ định với cú pháp khác của =. Thông số này là tuỳ chọn, thông số AllowMultiple chỉ định một attribute có thể áp dụng nhiều hơn một lần đến cùng một mục. Nếu thiết đặt là false thì trình biên dịch sẽ thông báo lỗi nếu nó thấy: [TenTruong("SOCMND")] [TenTruong("SOBaoHiem")] public string SOCMND { // vv... Nếu thông số Inherited là true, thì một thuộc tính có thể áp dụng đến một lớp hay một giao diện cũng sẽ được áp dụng đến tất cả các lớp hay giao diện được kế thừa. Nếu 106 thuộc tính được áp dụng cho phương thức hay thuộc tính thì nó tự động áp dụng đến bất kì phương thức hay thuộc tính nào được khái báo override. Đặc tả các thông số thuộc tính Ta sẽ kiểm tra làm thế nào ta có thể chỉ định thông số cho thuộc tính tuỳ chọn, Khi trình biên dịch gặp lệnh: [TenTruong("SOCMND")] public string SOCMND { ... Nó kiểm tra thông số truyền vào attribute , trong trường hợp này là chuỗi và tìm phương thức tạo lập của thuộc tính mà nhận các thông số này, nếu thấy thì không có vấn đề gì ngược lại trình biên dịch sẽ sinh ra lỗi. Các thông số tuỳ chọn Ta thấy thuộc tính attributeUsage có một cú pháp cho phép thêm các giá trị vào trong thuộc tính. Cú pháp này có liên quan đến việc chỉ định tên của các thông số được chọn. Giả sử ta cập nhật lại thuộc tính SoCMND như sau: [TenTruong("SoCMND ", ChuThich="Day la truong khoa")] public string SoCMND { ... Trong trường hợp này, trình biên dịch sẽ nhận ra= cú pháp của thông số thứ hai. Nó sẽ tìm một thuộc tính public (hoặc field) của tên đó mà nó có thể dùng để đặt giá trị của thông số này. Nếu ta muốn đoạn mã trên làm việc ta thêm mã sau vào TenTruongattribute: [attributeUsage(attributeTargets.Property, AllowMultiple=false, Inherited=false)] public class TenTruongattribute: attribute { private string chuthich; public string ChuThich { ... 9. 2 Reflection Reflection là một kĩ thuật cho phép ta tìm ra thông tin về các kiểu dữ liệu trong chương trình. Hầu hết những lớp này nằm trong namespace System.Reflection. Lớp System.Type cho phép ta truy nhập thông tin liên quan đến việc định nghĩa bất kì kiểu dữ liệu nào. Lớp System.Type Ta dùng lớp Type để lấy tên của một kiểu: Type t = typeof(double); Mặc dù ta cho rằng Type là một lớp nhưng thực sự nó là một lớp cơ sở trừu tượng, bất cứ khi nào ta khởi tạo một đối tượng Type ta thực sự khởi tạo một lớp dẫn xuất của 107 Type. Type có một lớp dẫn xuất đáp ứng mỗi kiểu dữ liệu. Có 3 cách lấy một tham chiếu Type cho kiểu dữ liệu bất kì: Dùng tác tử typeof, tác tử này lấy tên của kiểu như là thông số. Dùng phương thức GetType(), mà tất cả các lớp kế thừa từ System.Object: double d = 10; Type t = d.GetType(); GetType() hữu ích khi ta có một tham chiếu đối tượng và không chắc đối tượng thực sự là thể hiện của lớp nào. Ta cũng có thể gọi phương thức static của lớp type, getType(): Type t = Type.GetType("System.Double"); Các thuộc tính của Type Một số thuộc tính lấy chuỗi chứa các tên khác nhau kết hợp với lớp: Thuộc tính Trả về Name tên của kiểu dữ liệu FullName tên đầy đủ bao gồm cả namespace Namespace tên namespace của kiểu dữ liệu. Có thể lấy tham chiếu đến kiểu đối tượng của các lớp liên quan: Thuộc tính Kiểu tham chiếu trả về tương ứng với BaseType kiểu cơ sở trực tiếp của kiểu này UnderlyingSystemType kiểu mà kiểu này ánh xạ trong thời gian chạy.NET Một số thuộc tính luận lý kiểm tra kiểu, ví dụ là một lớp hay một kiểu liệt kê... những thuộc tính này bao gồm: IsAbstract, IsArray, IsClassembly, IsEnum, IsInterface, IsPointer, IsPrimitive, IsPublic, IsSealed, and IsValueType. Ví dụ dùng kiểu dữ liệu cơ bản: Type intType = typeof(int); Console.WriteLine(intType.IsAbstract); // false Console.WriteLine(intType.IsClassembly); // false Console.WriteLine(intType.IsEnum); // false Console.WriteLine(intType.IsPrimitive); // true Console.WriteLine(intType.IsValueType); // true hoặc dùng lớp Vector: Type intType = typeof(Vector);Console.WriteLine(intType.IsAbstract); // false Console.WriteLine(intType.IsClassembly); // true Console.WriteLine(intType.IsEnum); // false Console.WriteLine(intType.IsPrimitive); // false Console.WriteLine(intType.IsValueType); // false Các phương thức 108 Hầu hết các phương thức của System.Type được sử dụng để chứa chi tiết các thành viên của kiểu dữ liệu tương ứng - hàm tạo lập, thuộc tính, phương thức, sự kiện... có nhiều phương thức nhưng tất cả chúng đều theo nền chung. Ví dụ, có hai phương thức mà nhận chi tiết phương thức của kiểu dữ liệu: GetMethod() và GetMethods(). GetMethod() trả về một tham chiếu đến đối tượng System.Reflection. MethodInfo chứa chi tiết của một phương thức. GetMethods() trả vế một mảng tham chiếu. Ví dụ phương thức GetMethods() không lấy thông số nào và trả về chi tiết của tất cả phương thức thành viên của kiểu dữ liệu: Type t = typeof(double); MethodInfo [] methods = t.GetMethods(); foreach (MethodInfo nextMethod in methods) { ... Kiểu đối tượng trả về Các phương thức (phương thức số nhiều ( có 's' ở cuối tên ) trả về một mảng ) ConstructorInfo Gvvonstructor(), Gvvonstructors() EventInfo GetEvent(), GetEvents() FieldInfo GetField(), GetFields() InterfaceInfo GetInterface(), GetInterfaces() MemberInfo GetMember(), GetMembers() MethodInfo GetMethod(), GetMethods() PropertyInfo GetProperty(), GetProperties() Phương thức GetMember() và GetMembers() trả về chi tiết của bất kì hay tất cả thành viên của kiểu dữ liệu không cần biết đó là hàm tạo lập hay thuộc tính phương thức. Chương trình minh họa lấy tên của tất cả các phương thức của một lớp dùng reflection: using System; using System.Reflection; public interface IGiaoDien1 { void PhuongThucA(); } public interface IGiaoDien2 { void PhuongThucB(); } 109 public class ViDu : IGiaoDien1, IGiaoDien2 { public enum KieuLietKe { } public int nguyen; public string chuoi; public void PhuongThuc(int p1, string p2) { } public int ThuocTinh { get { return nguyen; } set { nguyen = value; } } void IGiaoDien1.PhuongThucA() { } void IGiaoDien2.PhuongThucB() { } } public class MainClass { public static void Main(string[] args) { ViDu f = new ViDu(); Type t = f.GetType(); MethodInfo[] mi = t.GetMethods(); foreach (MethodInfo m in mi) Console.WriteLine("Phuong Thuc: {0}", m.Name); } } 110 Hướng dẫn phần thực hành Sinh viên hoàn thành các chương trình mẫu được minh họa trên lớp. Sinh viên hoàn thành các bài thực hành từ bài Lab1 đến Lab5. Các bài thực hành này sẽ được cung cấp theo các buổi thực hành. Tài liệu tham khảo 1) Bài giảng Nguyên l í lập trình 2 2) Trang chiếu về lập trình C# của Microsoft. 3) Professional C#, 3rd Edition. NXB: Wrox, 2005. 4) C# How to Program, NXB: Prentice Hall, 2003. 5) Tài nguyên học tập tại
File đính kèm:
- Bài giảng tóm tắt Lập trình hướng đối tượng.pdf