Mục tiêu chính trong Bài giảng Lập trình hướng đối tượng trong C # Chương 5 Thiết kế và đa hình nhằm trình bày về thừa kế là gì? cài đặt thừa kế, nêu khái niệm đa hình.
CHƯƠNG THỪA KẾ VÀ ĐA HÌNH Nội dung Thừa kế gì? Cài đặt thừa kế Đa hình Thừa kế gì? C# cho phép tạo lớp từ lớp tồn Lớp B kế thừa lớp A, có nghĩa lớp B có thuộc tính phương thức A, ngoại trừ thành phần private – Lớp B gọi lớp hay lớp dẫn xuất – Lớp A gọi lớp cha hay lớp sở Một số kiểu thừa kế Một số kiểu thừa kế Một số kiểu thừa kế Cài đặt thừa kế Cú pháp khai báo lớp dẫn xuất từ lớp sở sau: Cú pháp định nghĩa lớp dẫn xuất: class TênLớpCon : TênLớpCơSở { // Thân lớp dẫn xuất } Ví dụ using System; //Lop co so Point2D class Point2D { class PointApp { public static void Main() { public int x,y; public void Xuat2D() { Console.WriteLine("({0}, {1})", x, y); Point2D p2 = new Point2D(); p2.x = 1; p2.y = 2; p2.Xuat2D(); Point3D p3 = new Point3D(); p3.x = 4; p3.y = 5; p3.z = 6; p3.Xuat3D(); p3.Xuat2D(); Console.ReadLine(); } } //Lop dan xuat Point3D ke thua tu lop Point2D class Point3D:Point2D { public int z; public void Xuat3D() { Console.WriteLine("({0}, {1}, {2})", x, y, z); } } } } Ví dụ using System; //Lop co so class Point2D { public int x,y; //phuong thuc tao lap cua lop co so co tham so public Point2D(int a, int b) { x = a; y = b; } public void Xuat2D() { Console.Write("({0}, {1})", x, y); } } Ví dụ (tt) //Lop dan xuat class Point3D:Point2D { public int z; class PointApp { public static void Main() { //Vi phuong thuc tao lap cua lop co so co tham so nen //phuong thuc tao lap cua lop dan xuat cung phai co tham so public Point3D(int a, int b, int c):base (a,b) { z = c; } public void Xuat3D() { Console.Write("({0}, {1}, {2})", x, y, z); } Point2D p2 = new Point2D(1, 2); Console.Write("Toa cua diem D :"); p2.Xuat2D(); Console.WriteLine(); Point3D p3 = new Point3D(4,5,6); Console.Write("Toa cua diem D :"); p3.Xuat3D(); Console.ReadLine(); } } } Đa hình Đa hình việc lớp B thừa kế đặc tính từ lớp A có thêm số cài đặt riêng Đa hình cách dùng nhiều dạng kiểu mà không quan tâm đến chi tiết Tạo phương thức đa hình Tạo phương thức đa hình, ta cần đặt từ khoá virtual phương thức lớp sở Ví dụ: public virtual void DrawWindow( ) Tạo phương thức đa hình Trong lớp kế thừa để nạp chồng lại mã nguồn lớp sở ta dùng từ khoá override khai báo phương thức nội dung bên viết bình thường Ví dụ nạp chồng phương thức DrawWindow: public override void DrawWindow( ) { base.DrawWindow( ); // gọi phương thức lớp co sở Console.WriteLine ("Writing string to the listbox: {0}“, listBoxContents); } Dùng hình thức đa hình phương thức tuỳ kiểu khai báo đối tượng dùng phương thức lớp Tạo phiên với từ khoá new override Khi cần viết lại phương thức lớp kế thừa mà có lớp sở ta không muốn nạp chồng lại phương thức virtual lớp sở ta dùng từ khoá new đánh dấu trước từ khoá virtual lớp kế thừa public class ListBox : Window { public new virtual void Sort( ) { } Lớp trừu tượng Phương thức trừu tượng phương thức có tên thơi phải cài đặt lại tất các lớp kế thừa Lớp trừu tượng thiết lập sở cho lớp kế thừa mà khơng thể có thể tồn Cú pháp khai báo phương thức trừu tượng: abstract public void TênPhươngThức( ); Ví dụ Xây dựng lớp HinhHoc với phương thức tính chu vi, diện tích phương thức trừu tượng phương thức ảo Sau định nghĩa lớp HinhChuNhat (hình chữ nhật), HinhTron (hình trịn) kế thừa từ lớp HinhHọc với thành phần liệu phương thức tính chu vi, diện tích cụ thể loại đối tượng Ví dụ // lop hinh hoc (truu tuong) abstract public class HinhHoc { // lop hinh tron ke thua tu lop hinh hoc public class HinhTron : HinhHoc { double _bankinh; public double BanKinh { abstract public double DienTich(); virtual public double ChuVi() { return 0; get{ return _bankinh;} set{ _bankinh = value;} } public override double DienTich() { return _bankinh*_bankinh*3.1416; } } } public override double ChuVi() { return _bankinh*2*3.1416; } } Ví dụ 1(tt) // lop hinh chu nhat ke thua tu lop hinh hoc public class HinhChuNhat : HinhHoc { class Tester { static void Main(string[] args) { double _dai, _rong; public double ChieuDai { get{ return _dai;} set{ _dai = value;} HinhHoc h; HinhTron t = new HinhTron(); t.BanKinh = 5; Console.WriteLine("Thong tin ve hinh tron"); h = t; Console.WriteLine("Chu vi hinh tron: {0} ", h.ChuVi()); Console.WriteLine("Dien tich hinh tron:{0} ", h.DienTich()); HinhChuNhat n = new HinhChuNhat(); n.ChieuDai = 4; n.ChieuRong = 3; h = n; Console.WriteLine("Thong tin ve hinh chu nhat "); Console.WriteLine("Chu vi hinh chu nhat: {0}", h.ChuVi()); Console.WriteLine("Dien tich hinh chu nhat: {0}", h.DienTich()); Console.ReadLine(); } public double ChieuRong { get{ return _rong;} set{ _rong = value;} } public override double DienTich() { return _dai*_rong; } public override double ChuVi() { return (_dai+_rong)*2; } } } } Ví dụ Minh hoạ phương thức lớp trừu tượng using System; abstract public class Window { // ListBox derives from Window public class ListBox : Window { // constructor adds a parameter public ListBox(int top, int left, string contents): base(top, left) // call base constructor { listBoxContents = contents; } // an overridden version implementing the // abstract method public override void DrawWindow( ) { Console.WriteLine("Writing string to the listbox: {0}“, listBoxContents); } private string listBoxContents; // new member variable // constructor takes two integers to // fix location on the console public Window(int top, int left) { this.top = top; this.left = left; } // simulates drawing the window // notice: no implementation abstract public void DrawWindow( ); // these members are private and thus invisible // to derived class methods We'll examine this // later in the chapter protected int top; protected int left; } } Ví dụ (tt) public class Button : Window { public Button(int top, int left): base(top, left) { } // implement the abstract method public override void DrawWindow( ) { Console.WriteLine("Drawing a button at {0}, {1}\n", top, left); } } public class Tester { static void Main( ) { Window[] winArray = new Window[3]; winArray[0] = new ListBox(1,2,"First List Box"); winArray[1] = new ListBox(3,4,"Second List Box"); winArray[2] = new Button(5,6); for (int i = 0;i < 3; i++) { winArray[i].DrawWindow( ); } } } Chú ý Phân biệt từ khóa new override – Từ khóa override dùng để định nghĩa lại (ghi đè) phương thức ảo (virtual) phương thức trừu tượng (abstract) lớp sở, dùng với mục đích đa hình – Từ khóa new để che dấu thành viên lớp sở trùng tên với thành viên lớp dẫn xuất – Khi cần viết lại phương thức lớp kế thừa mà có lớp sở, ta khơng muốn nạp chồng lại phương thức virtual lớp sở ta dùng từ khoá new đánh dấu trước từ khoá virtual lớp kế thừa Giới hạn lớp trừu tượng Ví dụ trên, phương thức trừu tượng DrawWindow() lớp trừu tượng Window lớp ListBox kế thừa Như vậy, lớp sau kế thừa từ lớp ListBox phải thực lại phương thức DrawWindow(), điểm giới hạn lớp trừu tượng Hơn nữa, sau không ta tạo lớp Window nghĩa Do vậy, nên chuyển lớp trừu tượng thành giao diện trừu tượng ... phương th? ?c có tên thơi phải c? ?i đặt lại tất c? ?c lớp kế thừa Lớp trừu tượng thiết lập sở cho lớp kế thừa mà khơng thể c? ? thể tồn C? ? pháp khai báo phương th? ?c trừu tượng: abstract public void TênPhươngTh? ?c( ... xuat class Point3D:Point2D { public int z; class PointApp { public static void Main() { //Vi phuong thuc tao lap cua lop co so co tham so nen //phuong thuc tao lap cua lop dan xuat cung phai co... HinhH? ?c với thành phần liệu phương th? ?c tính chu vi, diện tích c? ?? thể loại đối tượng Ví dụ // lop hinh hoc (truu tuong) abstract public class HinhHoc { // lop hinh tron ke thua tu lop hinh hoc public