Bài giảng Lập trình Windows - Chương 8: Object-Based Programming

Class và Object Object-Oriented Programming (OOP). Abstraction – Trừu Tượng Encapsulation – Đóng Gói Inheritance – Kế Thừa Polymorphism – Đa Hình Class and Object (Lớp và đối tượng) Class (Lớp) thực chất là một kiểu dữ liệu được định nghĩa trong chương trình. Class đặc trưng cho một mẫu, những nét chung nhất của một vài đối tượng và mô tả cấu trúc bên trong của những đối tượng này. Thể hiện (instance) của một lớp được gọi là những đối tượng (object). Những đối tượng này được tạo trong bộ nhớ khi chương trình được thực hiện. Những đối tượng của cùng một class có cùng định nghĩa về các thao tác và cấu trúc dữ liệu của chúng

ppt138 trang | Chia sẻ: candy98 | Lượt xem: 564 | Lượt tải: 0download
Bạn đang xem trước 20 trang tài liệu Bài giảng Lập trình Windows - Chương 8: Object-Based Programming, để xem tài liệu hoàn chỉnh bạn click vào nút DOWNLOAD ở trên
1Chapter 9 – Object-Based ProgrammingOutline Introduction Implementing a Time Abstract Data Type with a Class Class Scope Controlling Access to Members Initializing Class Objects: Constructors Using Overloaded Constructors Properties Composition: Objects as Instance Variables of Other Classes Using the this Reference Garbage Collection static Class Members const and readonly Members Indexers Data Abstraction and Information Hiding Software Reusability Namespaces and Assemblies Class View and Object Browser Interface2Giới ThiệuClass và ObjectObject-Oriented Programming (OOP).Abstraction – Trừu Tượng Encapsulation – Đóng GóiInheritance – Kế Thừa Polymorphism – Đa Hình3Class and Object (Lớp và đối tượng)Class (Lớp) thực chất là một kiểu dữ liệu được định nghĩa trong chương trình.Class đặc trưng cho một mẫu, những nét chung nhất của một vài đối tượng và mô tả cấu trúc bên trong của những đối tượng này.Thể hiện (instance) của một lớp được gọi là những đối tượng (object). Những đối tượng này được tạo trong bộ nhớ khi chương trình được thực hiện.Những đối tượng của cùng một class có cùng định nghĩa về các thao tác và cấu trúc dữ liệu của chúng4ClassName- Properties+ MethodsClass and Object (Lớp và đối tượng)5Class and ObjectClass : là một khái niệm trừu tượng (Abstraction)Object: là một đối tượng thậtVí Dụ:Ca sĩ là 1 classCẩm Ly là một ca sĩ (Object)Thời gian là 1 classGiờ vào lớp là thời gian (Object)Giờ ra chơi là thời gian (Object)6Class and ObjectClass TimeProperty Giờ Phút GiâyMethod SetTime UniversalString ToStringEvent Class CaSiProperty SoBaiHat KieuToc GiongHatMethod Sub DonCa Sub TrinhDien Function KyTenLuuNiemEvent KhatNuoc7ConsolePropertes+ Write()+ Writeline()+ ReadLine()+ SystemSystem.Window.FormMath- PI- E+ Pow()+ Sqrt()+ Sin()+MessageBoxPropertes+ Show()+ Form- Text- Name + Close()+ Hide()+ Show()+ Class and Object (Lớp và đối tượng)8Giới ThiệuObject-Oriented Programming (OOP).Abstraction – Trừu Tượng Encapsulation – Đóng GóiInheritance – Kế Thừa Polymorphism – Đa Hình9Object-Oriented Programming (OOP) - AbstractionMô hình của một đối tượng được xác định qua:Đặc điểm (Characteristics)  Thuộc tính (properties)Hành vi (Behaviors)  Phương thức (methods)AbstractionRealityObject-Oriented Programming10OOP Terminology-EncapsulationSự kết hợp của các đặc điểm cùng với các hành vi của một đối tượng được gọi là một gói (package).Data hidingThuộc tính và các thủ tục bị ẩn.Người lập trình điều khiển các thuộc tính và các phương thức có sẵn tới các đối tượng khác. Khai báo là private11OOP Terminology-InheritanceCó khả năng tạo ra một lớp mới từ lớp đã tồn tại. Lớp tồn tại (original – lớp gốc) được gọi là lớp cơ sở (base), superclass, hay lớp cha (parent)Lớp được thừa kế được gọi là lớp được chuyển giao (derived), subclass, hay lớp con (child)Lớp con có một quan hệ “is a” với lớp cha của nó.12OOP Terminology-Inheritancenamespace OOP{ public partial class frmOOP_Programing : Form { . . .13OOP Terminology-InheritanceSự thừa kế (Inheritance) hỗ trợ khả năng tái sử dụng (reusability) Reusability – tạo ra một hàm của một đối tượng và hàm này có thể được sử dụng cho nhiều projects14OOP Terminology - PolymorphismLà những phương thức (Methods) có cùng tên nhưng thực hiện những công việc khác nhau. Phương thức Select thì khác nhau cho các đối tượng như radio buttons, check boxes, và list boxesCho phép một lớp có một hay nhiều phương thức cùng tên nhưng danh sách các đối số (argument lists) thì khác nhau.Polymorphism is the ability to take onmany shapes or forms.15Khai Báo Lớp - Declaration Class[Thuộc tính bổ sung truy cập] class [: Lớp cơ sở]{ }Định danh lớp chính là tên của lớp do người xây dựng chương trình tạo ra. Lớp cơ sở là lớp mà đối tượng sẽ kế thừa để phát triển. Tất cả các thành viên của lớp được định nghĩa bên trong thân của lớp, phần thân này sẽ được bao bọc bởi hai dấu ({}).Thuộc tính bổ sung truy cậpAccess modifier: public, protected, internal, protected internal, privateNếu ko khai báo lớp cơ sở thì C# mặc định xem lớp cơ sở là objectLớp luôn là kiểu dữ liệu tham chiếu trong C#Class Members 16Thiết kế lớpThêm class mới vào project: Project hshsTạo đối tượngTen_Lop object;object = new Ten_Lop (arg1, Arg2, );21Ten_Lop object = new Ten_Lop (arg1, argu2, );Tạo đối tượng22Thiết kế lớp (tt)CHinhCNprivate double mDai;private double mRong;// constructorspublic CHinhCN()public CHinhCN (double d, double r)// other methodspublic double ChuVi()public double DienTich()23Thiết kế lớp (tt)24Thiết kế lớp (tt)25Sử dụng lớp (tt)Tất cả các biến, phương thức được khai báo trong class sẽ có phạm vi class.Trong một class, các biến và phương thức có thể sử dụng bằng cách gọi tên của chúng.Bên ngoài class, các phương thức trong class không thể được gọi tên trực tiếp mà phải tham chiếu sử dụng toán tử (.): .26PropertyGetter/Setter là các phương thức:Getter: Cho phép đối tượng cung cấp giá trị của thuộc tính ra bên ngoàiSetter: Cho phép bên ngoài thay đổi giá trị của thuộc tính của đối tượng một cách có kiểm soátProperty:Được bổ sung vào C# để thay thế cách dùng getter/setter truyền thống2627Creating Properties in a Classprivate dataType ClassVariablepublic dataType PropertyName{ get { return ClassVariable; } set { ClassVariable = value; }}28Creating Properties in a Class (p 305)private int year;public int Year{ get { return year; } set { year =value ; }}29Creating Properties in a Class (p 395)private int year;public int Year{ get { return year; } private set { year =value ; }}.Những người ở bên ngoài không thể can thiệp vào các biến private này30Property – Ví dụĐặt vấn đề Lớp HocSinh có thuộc tính diemVan (điểm văn)Giá trị của diemVan phải từ 0 tới 10Bên ngoài có thể thấy và đổi giá trị của diemVanChỉ cho phép đưa giá trị mới (diemMoi) vào diemVan nếu giá trị mới là hợp lệ (từ 0 tới 10)3031PropertyDùng getter/setter31class HocSinh{ protected double diemVan=0; // public double GetDiemVan() { return diemVan; } public void SetDiemVan( double diemMoi) { if (0= 0 )35 radius = value;36 }37 }81Circle2.cs39 // tính bán kính40 public double Diameter()41 {42 return Radius * 2;43 }44 45 // Tình chu vi46 public double Circumference()47 {48 return Math.PI * Diameter();49 }50 51 // diện tích52 public override double Area()53 {54 return Math.PI * Math.Pow( Radius, 2 );55 }56 58 public override string ToString()59 {60 return "Center = " + base.ToString() +61 "; Radius = " + Radius;62 }82Circle2.cs64 // override property Name from class Point265 public override string Name66 {67 get68 {69 return "Circle2";70 }71 }72 73 } // end class Circle283Cylinder2.cs5 // Cylinder2 inherits from class Circle26 public class Cylinder2 : Circle27 {8 private double height; // Cylinder2 height11 public Cylinder2()12 { }13 // constructor17 public Cylinder2( int xValue, int yValue, double radiusValue,18 double heightValue ) : base( xValue, yValue, radiusValue )19 {20 Height = heightValue;21 }22 24 public double Height25 {26 get27 { return height; }30 31 set32 {34 if ( value >= 0 )35 height = value; 36 }37 } 84Cylinder2.cs40 public override double Area()41 {42 return 2 * base.Area() + base.Circumference() * Height;43 } 45 46 public override double Volume()47 {48 return base.Area() * Height;49 }50 52 public override string ToString()53 {54 return base.ToString() + "; Height = " + Height;55 }56 58 public override string Name59 {60 get61 {62 return "Cylinder2";63 }64 }66 } // end class Cylinder285AbstractShapesTest.cs6 public class AbstractShapesTest7 {8 public static void Main( string[] args )9 {10 Point2 point = new Point2( 7, 11 );12 Circle2 circle = new Circle2( 22, 8, 3.5 );13 Cylinder2 cylinder = new Cylinder2( 10, 10, 3.3, 10 );14 16 Shape[] arrayOfShapes = new Shape[ 3 ];17 19 arrayOfShapes[ 0 ] = point;20 22 arrayOfShapes[ 1 ] = circle;23 25 arrayOfShapes[ 2 ] = cylinder;26 27 string output = point.Name + ": " + point + "\n" +28 circle.Name + ": " + circle + "\n" +29 cylinder.Name + ": " + cylinder;86AbstractShapesTest.cs 33 foreach( Shape shape in arrayOfShapes )34 {35 output += "\n\n" + shape.Name + ": " + shape +36 "\nArea = " + shape.Area().ToString( "F" ) + 37 "\nVolume = " + shape.Volume().ToString( "F" );38 }39 40 MessageBox.Show( output, "Demonstrating Polymorphism" ); 41 }42 }87Program Output88Sealed ClassCòn gọi là lớp niêm phong, không cho phép lớp khác kế thừa nó, ngược với lớp abstract.88using System; sealed class MyClass { public int x; public int y; } class MainClass { public static void Main() { MyClass mC = new MyClass(); mC.x = 110; mC.y = 150; Console.WriteLine("x = {0}, y = {1}", mC.x, mC.y); } } 89Sealed method89using System; class MyClass1 { public int x; public int y; public virtual void Method() { Console.WriteLine("virtual method"); } }class MyClass : MyClass1 { public override sealed void Method() { Console.WriteLine("sealed method"); } }class MainClass { public static void Main() { MyClass1 mC = new MyClass(); mC.x = 110; mC.y = 150; Console.WriteLine("x = {0}, y = {1}", mC.x, mC.y); mC.Method(); } } Sử dụng sealed trước phương thức để ngăn ko cho lớp dẫn xuất override90Nested classLớp đựơc khai báo bên trong thân của lớp khác gọi là: inner class hay nested class, lớp kia gọi là outer classLớp nội có thể truy cập tất cả thành viên của lớp ngoài, kể cả privateLớp nội nằm trong lớp ngoài nên nó có thể là private với lớp ngoàiKhi lớp nội khai báo là public thì có thể truy xuất thông qua tên của lớp ngoài: outer_class.inner_class9091Nested class91public class Fraction{ private int numerator; private int denominator; public Fraction(int numerator, int denominator) { this.numerator = numerator; this.denominator = denominator; } public override string ToString() { string str = numerator.ToString() + "/" + denominator.ToString(); return s; } public class FractionArtist { public void Draw(Fraction f) { Console.WriteLine("Drawing the numerator {0}", f.numerator); Console.WriteLine("Drawing the denominator {0}", f.denominator); } }}Lớp nested classTruy xuất được thành phầnPrivate của lớp outer92Nested class92class Tester{ static void Main() { Fraction f1 = new Fraction(3, 4); Console.WriteLine("f1: {0}", f1.ToString()); Fraction.FractionArtist fa = new Fraction.FractionArtist(); fa.Draw(f1); }}Truy xuất lớp inner qua lớp outer, lớp outer tương tự như manespace93InterfaceInterface quy định các chức năng nhưng không mô tả cụ thể chúngPhương thức trong interfaceChỉ khai báo, không định nghĩaKhông có từ khóa phạm vi, luôn là publicInterface không thể chứa thuộc tínhTừ khóa: interface93Có thể xem interface như một bản hợp đồng, nếu lớp nào sử dụng (kế thừa) nó thì phải thực thi đầy đủ các mô tả (phương thức) trong hợp đồng (interface)94InterfaceMột interface có thể kế thừa từ nhiều interface khácMột lớp có thể kế thừa từ nhiều interfacePhải định nghĩa tất cả phương thức mà các interface "cha" quy địnhSự kế thừa interface phải đặt sau sự kế thừa lớpCác interface thường được đặt tên với tiền tố là “I” IFile, IComparable, IDisposable, IStorable, ICloneable 94[access modifier] interface [: base interface list]95Interface - example95public interface IStudent{ int StudentID { get; set; } void AddSubject(string subjectName);}Khai báo property StudentID gồm hàm get ,setKhai báo phương thức AddSubjectPhải định nghĩa {get,set} của StudentID và AddSubject ở lớp thực thi interface96Interface - example96public class Student : IStudent{ private int studentID = 0; private ArrayList subjects = null; public Student() {} public int StudentID { get { return studentID; } set { studentID = value; } } public void AddSubject(string subjectName) { subjects.Add(subjectName); }}Bắt buộc lớp student phải định nghĩa property Student và hàm AddSubject97Cơ chế Delegate & Event98Nội dungDelegateKhái niệm delegateThực thi delegateMulticast delegateGiải pháp cho hàm Sort tổng quátEventKhái niệm eventEvent & delegateCơ chế publishing & subscribingMinh họa cơ chế event99DelegateLớp đóng gói các phương thức (method signature)Dùng trong event-handling model của C#Đặc tính Type safeObject oriented mechanismDelegate là class:Có instanceCó thể chứa những tham chiếu đến 1 hay nhiều method100DelegateMột delegate định nghĩa một signatureReturn typeSequence of parameter typesTất cả các method có cùng signature có thể được add vào thể hiện của delegateDelegate instance có một danh sách các tham chiếu methodCho phép add (+) các methodCó thể remove (-) các method101Define delegatepublic delegate void MyDelegate1(int x, int y) Delegate cho dạng hàm: void Method( int, int )public delegate string MyDelegate2(float f) Delegate cho dạng hàm: string Method( float )102Instance delegatepublic void Method1(int x, int y){ }MyDelegate1 del1 = new MyDelegate1(Method1);public string Method2(float f){ }MyDelegate2 del2 = new MyDelegate2(Method2);103Call Delegateint x = 5, y = 10;del1(x, y);del1(10, 20);int y = 2;del1(100, y);Gọi del1float f =0.5f;string s;s = del2(f);string s = del2(100f);Gọi del2104Multi Castvoid Print(int x,int y) { Console.WriteLine(“x = {0}, y = {1}”, x, y);}void Sum(int x, int y) { Console.WriteLine(“Tong = {0}”, x+y);}MyDelegate1 mulDel = new MyDelegate1(Print);mulDel += new MyDelegate1(Sum);mulDel(5, 10); mulDel -= new MyDelegate1(Print);mulDel(5,10);105Demo 1106ProblemXây dựng hàm Sort tổng quát cho mảng đối tượng có kiểu bất kỳ107SolutionPhân tíchNếu đối tượng là kiểu số như int, long, float thì ko có vấn đềTrường hợp đối tượng phức khác?So sánh theo quy tắc nào108SolutionGiải pháp:Cho phép đối tượng tự quy định thứ tự của chúngSử dụng delegate để truyền phương thức so sánh này vào hàm Sortvoid Sort(object[] list, CompareObj cmp)Delegate này sẽ tham chiếu tới hàm Compare của lớp MyClass. Chính lớp MyClass sẽ quy định thứ tự của các đối tượng109SolutionMô tả delegate CompareObj cho hàm Sort:public delegate bool CompareObj(object o1,object o2)Trả về true: nếu o1 “trước” o2 false: ngược lại2 đối tượng cần so sánhTên của delegate110Solution public static void Sort(object[] objs, CompareObj cmp) { for(int i=0; i i; j--) if ( cmp( objs[j], objs[j-1] ) ) { Swap( objs[j], objs[j-1] ); } }Định nghĩa hàm Sort tổng quát cho các lớp Delegate sẽ trỏ tới hàm Compare riêng của lớp tương ứngYêu cầu lớp tự so sánh111SolutionCác lớp hỗ trợ Sort thì phải Cung cấp hàm Compare riêngSignature phải thoả delegate CompareObjCùng signatureclass Person { private string name; private int weight; private int yearOfBirth; public static bool CompareName(object p1, object p2) { if (string.Compare(((Person)p1).name, ((Person)p2).name)<0) return true; return false; }}112Solution public delegate bool CompareObj(object o1,object o2); Person[ ] persons = new Person[4]; persons[0] = new Person(“Quy Mui", 2, 2004); persons[1] = new Person(“Ha Lam", 65, 1978); persons[2] = new Person(“Ngoc Thao", 47, 1979); persons[3] = new Person(“Quoc Trung", 65, 1932); CompareObj cmp = new CompareObj(Person.CompareName); Lib.Sort( persons, cmp );Gọi hàm SortLớp chứa hàm Sort113Event114EventCơ chế thông điệp giữa các lớp hay các đối tượngCó thể thông báo cho lớp khác biết được khi một lớp có phát sinh điều gì đóPublisher: lớp phát sinh sự kiệnSubscriber: lớp nhận hay xử lý khi sự kiện xảy ra115EventTrong môi trường giao diện GUIs (Graphical User Interfaces: GUIs):Button đưa ra sự kiện “Click”, cho phép lớp khác có thể đáp ứng (xử lý) khi sự kiện này xảy ra.VD: Button “Add” trong Form, khi sự kiện click xảy ra thì Form thực hiện lấy dữ liệu từ các TextBox đưa vào ListBox116Publishing & SubscribingMột lớp có publish một tập các event cho phép các lớp khác subscribeButton là lớp publish đưa ra event: click Form là lớp subscribe có phần xử lý riêng khi “click” của Button kích hoạt.ABCeventpublishsubscribeThông báoĐăng ký117Event & DelegateSự kiện trong C# được thực thi nhờ uỷ thácLớp publishing định nghĩa ủy thácNhững lớp subscribing phải thực thiKhi sự kiện xuất hiện thì phương thức của lớp subscribing được gọi thông qua uỷ thác.Phương thức để xử lý sự kiện gọi là trình xử lý sự kiện (event handler)118Event & DelegateTrình xử lý sự kiện trong .NET Framework được mô tả như sau:Trả về giá trị voidTham số 1: nguồn phát sinh sự kiện, đây chính là đối tượng publisherTham số 2: là đối tượng thuộc lớp dẫn xuất từ EventArgsPhải thực hiện trình xử lý sự kiện theo đúng mẫu trên!119Event & DelegateKhai báo delegate xử lý sự kiệnKhai báo eventCác lớp muốn xử lý khi sự kiện OnEventName phát sinh thì phải thực thi event handlerpublic delegate void HandlerName(object obj, EventArgs arg);public event HandlerName OnEventName;120Minh họa 1Xây dựng 1 lớp thực hiện yêu cầu: “cứ mỗi giây sẽ phát sinh 1 sự kiện”Cho phép 2 lớp khác đăng ký xử lý sự kiện này, mỗi lớp có cách xử lý riêng:Lớp A: hiển thị thời gian theo “mô phỏng đồng hồ analog”Lớp B: hiển thị thời gian theo “mô phỏng đồng hồ digital”121Minh họa 1Tạo một lớp Clock:Khai báo một event: OnSecondChangeMột phương thức Run: cứ 1s thì phát sinh sự kiện OnSecondChangeTạo 2 lớp: AnalogClock và DigitalClock nhận xử lý sự kiện OnSecondChange của lớp Clock122Minh họa 1Khai báo delegate xử lý eventdelegate void SecondChangeHandler(object clock, EventArgs info);Tên delegate xử lý sự kiệnĐối tượng phát sinh eventTham số kiểu EventArgs123Minh họa 1Khai báo event có hàm xử lý mô tả trên event SecondChangeHandler OnSecondChange;Kiểu delegateTên của eventTừ khóa event: thể hiện cơ chế publishing & subscribing124Minh họa 1Kích hoạt sự kiệnif (OnSecondChange != null) OnSecondChange(this, new EventArgs());Gọi hàm xử lý sự kiện đã đăng kýKiểm tra xem có hàm xử lý được đăng ký hay không?125Minh họa 1public class Clock {public delegate void SecondChangeHandler(object clock, EventArgs info); public event SecondChangeHandler OnSecondChange; public void Run() { while (true) { Thread.Sleep(1000); if (OnSecondChange != null) OnSecondChange(this, new EventArgs()); } }}126Minh họa 1Lớp DigitalClockĐịnh nghĩa trình xử lý sự kiện của ClockĐúng mô tả delegate hàm xử lý của lớp ClockThực hiện một số thao tác riêng của DigitalClockĐăng ký xử lý với trình xử lý sự kiện trên khi có sự kiện OnSecondChange của ClockChức năng đăng ký với lớp Clock là có xử lý khi sự kiện OnSencondChange của Clock phát sinhỦy thác cho lớp Clock sẽ gọi trình xử lý định nghĩa bên trên của DigitalClock127Minh họa 1Trình xử lý của DigitalClockpublic void Show(object obj, EventArgs args){ DateTime date = DateTime.Now; Console.WriteLine("Digital Clock: {0}:{1}:{2}", date.Hour, date.Minute, date.Second);}Tên của trình xử lýĐối tượng phát sinh sự kiện128Minh họa 1Đăng ký xử lý sự kiện public void Subscribe(Clock theClock) { theClock.OnSecondChange += new Clock.SecondChangeHandler(Show); }Đối tượng này sẽ phát sinh sự kiệnỦy thác phương thức Show cho OnSecondChange129Minh họa 1public class DigitalClock{ public void Subscribe(Clock theClock) { theClock.OnSecondChange += new Clock.SecondChangeHandler(Show); } public void Show(object obj, EventArgs args) { DateTime date = DateTime.Now; Console.WriteLine("Digital Clock: {0}:{1}:{2}", date.Hour, date.Minute, date.Second); }}130Minh họa 1Lớp AnalogClockĐịnh nghĩa trình xử lý sự kiện của ClockĐúng mô tả delegate hàm xử lý của lớp ClockThực hiện một số thao tác riêng của AnalogClockĐăng ký xử lý với trình xử lý sự kiện trên khi có sự kiện OnSecondChange của ClockChức năng đăng ký với lớp Clock là có xử lý khi sự kiện OnSencondChange của Clock phát sinhỦy thác cho lớp Clock sẽ gọi trình xử lý định nghĩa bên trên của AnalogClock131Minh họa 1public class AnalogClock{ public void Subscribe(Clock theClock) { theClock.OnSecondChange += new Clock.SecondChangeHandler(Show); } public void Show(object obj, EventArgs args) { DateTime date = DateTime.Now; Console.WriteLine("Analog Clock: {0}:{1}:{2}", date.Hour,date.Minute,date.Second); }}132Minh họa 1Minh họa cơ chế eventpublic class Tester { public static void Main() { Clock myClock = new Clock(); AnalogClock c1 = new AnalogClock(); DigitalClock c2 = new DigitalClock(); c1.Subscribe(myClock); c2.Subscribe(myClock); myClock.Run(); }}Đăng ký xử lý sự kiện của đối tượng myClock!Phát sinh sự kiệ