Lập trình Windows - Chương 2: Ngôn ngữ lập trình C# - Phần 2
Field: Field là một biến thành viên dùng để lưu giữ giá trị của một đối tượng
Property: Property là mở rộng của field, dùng để cung cấp giá trị mà không cần phải tốn bộ nhớ lưu trữ giá trị (field thông minh – smart field)
96 trang |
Chia sẻ: huyhoang44 | Lượt xem: 626 | Lượt tải: 0
Bạn đang xem trước 20 trang tài liệu Lập trình Windows - Chương 2: Ngôn ngữ lập trình C# - Phần 2, để xem tài liệu hoàn chỉnh bạn click vào nút DOWNLOAD ở trên
Lập trình WindowsChương 2. Ngôn ngữ lập trình C# Phần 21Nội dungInterfaceProperty, Mảng và IndexerLớp Collection2InterfaceInterfaceKhái niệmInterfaceKhái niệmInterface định nghĩa một “giao kèo” mà có thể được hiện thực bởi các lớpMột interface có thể chứa các methods, properties, events, và indexers Interface không cung cấp các hiện thực của các thành viên nó định nghĩaInterface là một lớp trừu tượng thuần túyInterfaceKhai báoCú pháp[attributes][modifiers]interface[:baseList]{ [interface-body]}InterfaceKhai báointerface IControl{ void Paint();}Tên InterfaceĐặt giống như tên lớpKý tự đầu tiên là “I”InterfaceKhai báoDanh sách thừa kếInterface chỉ có thể thừa kế từ các interface khácInterface có thể thực hiện đa thừa kế interface IControl{ void Paint();}interface ITextBox: IControl{ void SetText(string text);}interface IListBox: IControl{ void SetItems(string[] items);}interface IComboBox: ITextBox, IListBox {}InterfaceKhai báoCác thành phần bên trong interfacePhương thứcPropertyIndexerEventVà các thành phần khác được thừa kế từ các interfaceNhận xétKhông có field trong interfaceKhông có constructor và destructorKhông có kiểu lồng nhauKhông được viết access modifier cho các thành viênInterfaceHiện thựcQuy tắcMột lớp có thể hiện thực một hay nhiều interfaceKhi một lớp cài đặt interface phải cài đặt mọi thành viên trong các interface đóCách hiện thựcDùng thành viên publicHoặc chỉ rõ thành viên thuộc interface nào (tránh tạo thành viên public)InterfaceHiện thựcCú phápclass ClassName: InterfaceList{ public InterfaceMember() {} InterfaceName.InterfaceMember() {}}21InterfaceHiện thựcinterface IControl{ void Paint();} interface IDataBound{ void Bind(Binder b);}public class EditBox: IControl, IDataBound{ public void Paint() { } public void Bind(Binder b) { ... }} Cách 1InterfaceHiện thựcKhi một lớp hay một struct hiện thực một interface thì các instances của lớp/struct đó có thể được chuyển ngầm định sang kiểu interface đóEditBox editBox = new EditBox();editBox.Paint();IControl control = editBox;IDataBound dataBound = editBox;control.Paint();dataBound.Bind();InterfaceHiện thựcinterface IControl{ void Paint();} interface IDataBound{ void Bind(Binder b);}public class EditBox: IControl, IDataBound{ public void IControl.Paint() { } public void IDataBound.Bind(Binder b) { ... }} Cách 2InterfaceHiện thựcChú ý: các thành viên hiện thực bằng cách 2 chỉ có thể truy cập qua kiểu interfaceEditBox editBox = new EditBox();editBox.Paint(); IControl control = editBox;control.Paint(); InterfaceHiện thựcpublic interface IFile{ int DeleteFile(); void DisplayFile();}public class MyFile : IFile{ public int DeleteFile() { Console.WriteLine("DeleteFile Implementation!"); return(0); } public void DisplayFile() { Console.WriteLine("DisplayFile Implementation!"); }}InterfaceHiện thựcclass InterfaceDemo{ public static void Main() { MyFile objMyFile = new MyFile(); objMyFile.DisplayFile(); int retValue = objMyFile.DeleteFile(); }} InterfaceHiện thựcHiện thực nhiều interfacepublic interface IFileTwo{ void ApplySecondInterface();}InterfaceHiện thựcpublic class MyFile: IFile, IFileTwo{ public int DeleteFile() { Console.WriteLine ("DeleteFile Implementation!"); return(0); } public void DisplayFile() { Console.WriteLine("DisplayFile Implementation!"); } public void ApplySecondInterface() { Console.WriteLine("ApplySecondInterface Implementation!"); }}InterfaceHiện thựcclass MultipleInterfaces{ static void Main() { MyFile objMyFile = new MyFile(); objMyFile.DisplayFile(); int retValue = objMyFile.DeleteFile(); objMyFile.ApplySecondInterface(); }} InterfaceHiện thựcÝ nghĩa của cách hiện thực “Chỉ rõ thành viên thuộc interface nào”Ẩn thành viên đối với bên ngoài lớpTránh trùng tên trong đa thừa kế interfaceAbstract class và InterfaceAbstract classInterfaceCó thành viên abstract và không abstractTất cả thành viên ngầm định là abstract Định nghĩa lớp abstract có các thành viên abstract = định nghĩa interface Có thể có các phần protected, phương thức Thành viên của interface là public không có hiện thực Chỉ được thừa kế từ 1 lớp abstractMột lớp có thể thừa kế từ 1 hay nhiều interfaces Lớp abstract có thể thêm nhiều chức năng mà không phá hủy các lớp conTạo thêm chức năng sẽ ảnh hưởng đến lớp coninterface-virtual-override-sealedInterface chỉ ra tên của phương thứcVirtual là implement đầu tiên của phương thứcOverride là implement khác của phương thứcSealed là implement cuối cùng của phương thức Bài tậpDùng phương thức tĩnh Array.Sort() để sắp xếp các đối tượng của một lớp nào đóHướng dẫn: Để dùng phương thức Sort() các phần tử của mảng phải implement giao diện IComparable public interface IComparable { int CompareTo(object obj); }Property – Mảng – IndexerPropertyKhái niệmField: Field là một biến thành viên dùng để lưu giữ giá trị của một đối tượngProperty: Property là mở rộng của field, dùng để cung cấp giá trị mà không cần phải tốn bộ nhớ lưu trữ giá trị (field thông minh – smart field) PropertyKhái niệmclass MyClass{ public int data; public int ABC { get {} set {} } } MyClass sp = new MyClass();// Đọc dữ liệu x = sp.data;x = sp.ABC; // Ghi dữ liệu sp.data = x;sp.ABC = x;PropertyProperty và FieldGiống nhauCả hai là thành viên có tên và có kiểu Cú pháp truy cập field và property giống nhauKhác nhauProperty không giành bộ nhớ chứa dữ liệu Property có các accessor chứa các câu lệnh được thực thi khi giá trị của chúng được đọc hay ghiPropertyĐịnh nghĩa { get { return ; } set { } } get accessorset accessorCú phápPropertyĐịnh nghĩaGet accessorĐược gọi khi bên ngoài đọc dữ liệu của propertyGet accessor tương đương với phương thức không tham số với giá trị trả về thuộc kiểu của propertyKhi property được tham chiếu trong biểu thức thì get accessor được thực thi để tính giá trị của propertySet accessorĐược gọi khi bên ngoài ghi dữ liệu vào propertySet accessor tương đương với phương thức có một tham số được đặt tên là value và không có kiểu trả vềKhi property được tham chiếu ở bên trái phép gán hay toán tử ++ hoặc -- thì get accessor được thực thi với một tham số là giá trị mớiPropertyĐịnh nghĩaclass MyClass{ Random random = new Random(); public int Data { get { Console.WriteLine(“GET”); return random.Next(1, 100); } set { Console.WriteLine(“SET ” + value); } }}PropertyĐịnh nghĩaclass Program{ static void Main() { MyClass obj = new MyClass(); int x; x = obj.Data; Console.WriteLine(x); obj.Data = x+1; }}PropertyProperty và Phương thức truy cập Phương thức truy cậpĐể bên ngoài lớp truy cập các field trong một lớp thì lớp đó phải cung cấp các phương thức public: gọi là phương thức Get, phương thức Setclass ScreenPosition { private int x, y; public int GetX() { return x; } public void SetX(int newX) { x = newX; } } Lấy giá trị của fieldThay đổi giá trị của fieldPropertyProperty và Phương thức truy cậpPublic Propery là cách thức khác giúp chúng ta tạo ra cách truy cập các field trong lớp nhưng tự nhiên hơn cho người sử dụng lớpclass ScreenPosition{ private int x, y; public int X { get { return x; } set { x = value; } } public int Y { get { return y; } set { y = value;} } } PropertyProperty và Phương thức truy cậpclass Progam{ static void Main() { ScreenPosition pos = new ScreenPosition(); oldData = pos.X; pos.X = newData; }}Gọi phương thức getterGọi phương thức setterPropertyTương tự các fields và methods, C# hỗ trợ cả instance properties và static properties. Static properties được khai báo với static modifier.Các accessor của property có thể là virtual. Khi property khai báo có modifier là virtual, abstract hay override, nó cũng áp dụng cho cả các accessor của property đó.MảngMảngKhái niệmMảngMảng là một cấu trúc dữ liệu chứa một số biến được truy cập thông qua chỉ mục. Các biến trong mảng, cũng được gọi là các phần tử, có cùng kiểu Đặc điểm mảng trong C#Mảng là kiểu tham chiếuTất cả các kiểu mảng đều có lớp cơ sở: System.Array MảngKhái niệmPhân loại mảng trong C#Mảng một chiềuMảng nhiều chiềuMảng zic zacMảng hỗn hợpMảngKhai báoMảng hỗn hợptype [ ] arrayName;type [,] arrayName;type [,,] arrayName;type [ ][ ] arrayName;type [ ][,,][,] arrayName;Mảng 1 chiềuMảng nhiều chiềuMảng zich zắc arrayNamenullMảngBộ khởi tạotype [ ] arrayName = {v1, v2, , vn};type [ ] arrayName = new type [ ]{v1, v2, , vn};type [ ] arrayName = new type [n]{v1, v2, , vn};type [,] arrayName = { {v1,v2,,vn}, , {v1,v2,,vn}};type [,] arrayName = new type[,] {};type [,] arrayName = new type[n1, n2] {};Mảng 1 chiềuMảng nhiều chiềuMảngBộ khởi tạotype[ ][ ] arrayName = { new type[ ]{v1,vn}, new type[ ]{v1, , vm}, };type[ ][ ] arrayName = { new type[n]{v1,vn}, new type[m]{v1, , vm}, };type[ ][ ] arrayName = new type[][ ] { new type[ ]{v1,vn}, new type[ ]{v1, , vm}, };type[ ][ ] arrayName = new type[n][ ] { new type[ ]{v1,vn}, new type[ ]{v1, , vm}, };Mảng zich zắc Đúng n phần tửĐúng n dòngMảngTruy cập các phần tửMảng 1 chiềuarrayName[x];arrayName[x, y];arrayName[x, y, z];arrayName[x][y];Mảng zich zắc Mảng nhiều chiềuMảngTạoTạo mảng Dùng bộ khởi tạoDùng toán tử newĐể lấy số phần tử của mảng chúng ta dùng thuộc tính arrayName.LengthMảngTạoMảng 1 chiềuarrayName = new type[n];type [ ] arrayName = new type [n];arrayName = new type[n1, n2];type [,] arrayName = new type [n1, n2];type [ ][ ] arrayName = new type [n][ ];arrayName[0] = new type[m1];arrayName[1] = new type[m2];arrayName[n] = new type[mn];Mảng zich zắc Mảng nhiều chiềuMảngTạoarrayNamearrayNamearrayNamearrayName[0]arrayName[1]arrayName[2]arrayNamenullMảngMảng giá trị - Mảng tham chiếuMảng kiểu giá trị579int arrayName = new int[3]{5,7,9};arrayNameSTACKHEAPMảngMảng giá trị - Mảng tham chiếuMảng đối tượngaccountSTACKHEAPnullnullnullBankAccount account = new BankAccount[3];account[0]account[1]account[2]MảngMảng giá trị - Mảng tham chiếuMảng đối tượngaccount[0] = new BankAccount();accountnullnullaccount[0]account[1]account[2]:BankAccountMảngMảng và phương thứcKiểu trả về của phương thức là mảngtype[ ] MethodName(){ type[ ] result; return result;}MethodName(type[ ] arrayName){ }Tham số của phương thức là mảngMảngSao chép MảngMảng là kiểu tham chiếu. Khi sao chép 1 biến mảng sang 1 biến mảng khác, chúng ta sẽ có 2 tham chiếu đến cùng 1 instance mảng1234int[] x = {1,2,3,4,5};5int[] y;nully=x;xy12345xyMảngSao chép MảngNếu muốn sao chép các instance mà mảng đang tham chiếu đến chúng ta thực hiện 2 bướcTạo một instance mảng mớiThiết lập các giá trị trong mảng mới như mảng gốcint[] y = new int[x.Length];for (int i=0; i this [paramater-list] { get { // Return giá trị } set { // thiết lập giá trị mong muốn } } }Cú phápIndexer Ví dụclass IndexerExample{ public string[] stringList =new string[10]; public string this[int index] { get { return stringList[index]; } set { stringList[index] = value.ToString(); } }}Indexer Ví dụclass Test{ static void Main() { IndexerExample indexTest = new IndexerExample(); indexTest.stringList[1]="Sam"; indexTest[2]="Tom"; System.Console.WriteLine( "indexTest[1] is {0}\nindexTest[2] is {1}", indexTest[1], indexTest[2]); }} IndexerIndexer có nhiều tham sốNhiều tham số: indexer được truy cập như mảng nhiều chiều...class TestMultip{ public int this[int firstP, int secondP] { //Get and Set Accessors appear here }}...IndexerIndexer có nhiều tham số{ void static Main() { TestMultip myTest = new TestMultip(); int I = myTest[1,1]; }}Struct và EnumStructStruct: Struct là một CTDL có thể chứa các thành viên dữ liệu và các phương thức (phiên bản lightweight của class) Đặc điểm của structStruct là một kiểu giá trịKhông thể thừa kế Các field không được khởi tạo khi khai báoStructCú pháp[attributes][modifiers] struct [:interfaces] { [struct-body] }[;]Structstruct RGB { public int Red; public int Green; public int Blue;} RGB rgb; rgb.Red = 0xFF; rgb.Green = 0xFF; rgb.Blue = 0xFF;StructSử dụng structStruct thường được dùng cho các cấu trúc dữ liệu nhỏ mà có ngữ nghĩa là giá trịví dụ: Complex, Point, các cặp value-key trong dictionary Sử dụng struct thay cho class đối với các cấu trúc dữ liệu nhỏ có thể tạo khác biệt lớn về số lượng bộ nhớ được sử dụngStructclass Point{ public int x, y; public Point(int x, int y) { this.x = x; this.y = y; }}class Test{ static void Main() { Point[] points = new Point[100]; for (int i = 0; i list = new List();List list = new List(capacity);PropertiesCollectionsArrayList/ListThêm dữ liệulistName.Add(data);Truy cập dữ liệu listName[index];foreach (type variable in listName){ xử lý variable}CollectionsArrayList/ListXóa dữ liệu listName.Remove(data);Chèn dữ liệu listName.Insert(index, data);listName.Clear();Sắp xếplistName.Sort();CollectionsArrayList/ListTìm kiếm dữ liệu bool listName.Contains(data);int listName.IndexOf(data);int listName.LastIndexOf(data);CollectionsArrayList/ListChú ý: trong List thay object bằng kiểu tương ứng khi tạo ListMethods Ý nghĩaint Add(object)Thêm một đối tượng vào cuối mảngvoid Clear()Xóabool Contains(object)Kiểm tra có tồn tại một đối tượng trong mảngint IndexOf(object)Tìm kiếm từ trái sang phảiint LastIndexOf(object)Tìm kiếm từ phải sang tráivoid Insert(index, object)Chèn một đối tượng tại vị trívoid Remove(object)Xóa phần từvoid RemoveAt(index)Xóa phần tử tại vị trívoid RemoveRange(index, count)Xóa một số phần tửvoid Sort()Sắp xếp tăng dầnint BinarySearch(object)Tìm kiếm nhị phânvoid Reverse()ĐảoIEnumerator GetEnumeratorTrả về IEnumeratorCollectionsQueueQueue hiện thực collection FIFOPhương thứcvoid Enqueue(object): Thêm vào queueobject Dequeue() Lấy ra khỏi queueobject Peek(): Trả về phần tử đầu queue (nhưng không xóa khỏi queue)Property: int CountPhương thức khác: Clear(), Clone(), Contains(), CopyTo(), GetEnumerator(), Collections StackStack hiện thực collection LIFOPhương thứcvoid Push(object): Thêm vào stackobject Pop(): Lấy ra khỏi stackobject Peek(): Trả về phần tử trên đỉnh stack (nhưng không xóa khỏi stack)Property: int CountPhương thức khác: Peek(), Clear(), Clone(), Contains(), CopyTo(), GetEnumerator(), CollectionsTự Tạo collectionIterationforeach hoạt động như thế nào?Làm thế nào dùng foreach với lớp của chúng ta?Duyệt các phần tử CollectionArrayList a = new ArrayList();a.Add(1); a.Add(5); a.Add(3);foreach (int x in a){ Console.WriteLine(x);}ArrayList a = new ArrayList();a.Add(1); a.Add(5); a.Add(3);IEnumerator ie = a.GetEnumerator();while (ie.MoveNext()){ int x = (int)ie.Current; Console.WriteLine (x);}CollectionsTự Tạo collectionCâu lệnh foreach làm việc trên collection mà collection thỏa quy tắc sauHoặc hiện thực interface IEnumerableHoặc hiện thực theo collection pattern:Collection phải có phương thức public GetEnumerator() không tham số và trả về kiểu struct, class hay interfaceKiểu trả về của phương thức GetEnumerator() phải chứaPhương thức public MoveNext() không tham số, kiểu trả về boolPhương thức public Current không tham số, kiểu trả về kiểu tham chiếuCollectionsTự Tạo collectionclass MyCollectionClass: IEnumerable{ ... }foreach (string s in myCollection){ Console.WriteLine("String is {0}", s);}IEnumerator ie = (IEnumerable) myCollection;IEnumerator e = ie. GetEnumerator(); while (e.MoveNext()){ string s = (string) e.Current; Console.WriteLine("String is {0}", s); }CollectionsTự Tạo collectionpublic interface IEnumerable{ IEnumerator GetEnumerator();}public interface IEnumerator{ object Current { get; } bool MoveNext(); void Reset();}CollectionsTự Tạo collectionclass MyCollectionClass : IEnumerable{ CollectionPart[] _parts; ... ... public IEnumerator GetEnumerator() { }}CollectionsTự Tạo collectionclass MyCollectionClass : IEnumerable{ CollectionPart[] _parts; ... ... public IEnumerator GetEnumerator() { return _parts.GetEnumerator() }}Vì _parts là System.Array, là một kiểu liệt kê nên nó có phương thức GetEumerator() trả về IEnumeratorCollectionsTự Tạo collectionGiải pháp : tiếp cận dựa trên mẫuTrình biên dịch C# compiler tìm kiếm:GetEnumerator() trên collectionbool MoveNext() trên kiểu enumeratorCurrent trên kiểu enumeratorQ&A96
Các file đính kèm theo tài liệu này:
- lap_trinh_tren_windows_chuong2_ngonngulaptrinhc_part2_721.pptx