C# cho phép tạo ra một lớp mới từ các lớp đã tồn tại.
Lớp B kế thừa lớp A, có nghĩa là lớp B sẽ có các thuộc tính và phương thức của A, ngoại trừ các thành phần private.
Lớp B được gọi là lớp con hay lớp dẫn xuất.
Lớp A được gọi là lớp cha hay lớp cơ sở.
22 trang |
Chia sẻ: lylyngoc | Lượt xem: 1880 | Lượt tải: 0
Bạn đang xem trước 20 trang tài liệu Chương 5 Thừa kế và đa hình, để xem tài liệu hoàn chỉnh bạn click vào nút DOWNLOAD ở trên
CHƯƠNG 5THỪA KẾ VÀ ĐA HÌNH Nội dung chính Thừa kế là gì? Cài đặt thừa kế Đa hình 1. Thừa kế là gì? C# cho phép tạo ra một lớp mới từ các lớp đã tồn tại. Lớp B kế thừa lớp A, có nghĩa là lớp B sẽ có các thuộc tính và phương thức của A, ngoại trừ các thành phần private. Lớp B được gọi là lớp con hay lớp dẫn xuất. Lớp A được gọi là lớp cha hay lớp cơ 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ế 2. Cài đặt thừa kế Cú pháp khai báo lớp dẫn xuất từ một lớp cơ sở như 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ụ 1 using System; //Lop co so Point2D class Point2D { public int x,y; public void Xuat2D() { Console.WriteLine("({0}, {1})", x, y); } } //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); } } class PointApp { public static void Main() { 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(); } } Ví dụ 2 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ụ 2 (tt) //Lop dan xuat class Point3D:Point2D { public int z; //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); } } class PointApp { public static void Main() { Point2D p2 = new Point2D(1, 2); Console.Write("Toa do cua diem 2 D :"); p2.Xuat2D(); Console.WriteLine(); Point3D p3 = new Point3D(4,5,6); Console.Write("Toa do cua diem 3 D :"); p3.Xuat3D(); Console.ReadLine(); } } 3. Đa hình Đa hình là việc lớp B thừa kế các đặc tính từ lớp A nhưng có thêm một số cài đặt riêng. Đa hình cũng là cách có thể dùng nhiều dạng của một 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 trong phương thức của lớp cơ 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 của lớp cơ sở ta dùng từ khoá override khi khai báo phương thức và nội dung bên trong viết bình thường. Ví dụ về nạp chồng phương thức DrawWindow: public override void DrawWindow( ) { base.DrawWindow( ); // gọi phương thức của 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 này thì tuỳ kiểu khai báo của đối tượng nào thì nó dùng phương thức của lớp đó. Tạo phiên bản với từ khoá new và override Khi cần viết lại một phương thức trong lớp kế thừa mà đã có trong lớp cơ sở nhưng ta không muốn nạp chồng lại phương thức virtual trong lớp cơ sở ta dùng từ khoá new đánh dấu trước khi từ khoá virtual trong 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 là phương thức chỉ có tên thôi và nó phải được cài đặt lại ở tất các các lớp kế thừa. Lớp trừu tượng chỉ thiết lập một cơ sở cho các lớp kế thừa mà nó không thể có bất kỳ một thể hiện nào tồn tại. 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 là phương thức trừu tượng hoặc phương thức ảo. Sau đó định nghĩa các lớp HinhChuNhat (hình chữ nhật), HinhTron (hình tròn) kế thừa từ lớp HinhHọc với các thành phần dữ liệu và phương thức tính chu vi, diện tích cụ thể của từng loại đối tượng. Ví dụ 1 // lop hinh hoc (truu tuong) abstract public class HinhHoc { abstract public double DienTich(); virtual public double ChuVi() { return 0; } } // lop hinh tron ke thua tu lop hinh hoc public class HinhTron : HinhHoc { double _bankinh; public double BanKinh { 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 { double _dai, _rong; public double ChieuDai { get{ return _dai;} set{ _dai = value;} } public double ChieuRong { get{ return _rong;} set{ _rong = value;} } public override double DienTich() { return _dai*_rong; } public override double ChuVi() { return (_dai+_rong)*2; } } class Tester { static void Main(string[] args) { 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(); } } Ví dụ 2 Minh hoạ phương thức và lớp trừu tượng using System; abstract public class Window { // 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; } // 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 } Ví dụ 2 (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 giữa từ khóa new và override Từ khóa override dùng để định nghĩa lại (ghi đè) phương thức ảo (virtual) hoặc phương thức trừu tượng (abstract) của lớp cơ sở, nó được dùng với mục đích đa hình. Từ khóa new để che dấu thành viên của lớp cơ sở trùng tên với thành viên của lớp dẫn xuất. Khi cần viết lại một phương thức trong lớp kế thừa mà đã có trong lớp cơ sở, nhưng ta không muốn nạp chồng lại phương thức virtual trong lớp cơ sở ta dùng từ khoá new đánh dấu trước khi từ khoá virtual trong lớp kế thừa. Giới hạn của lớp trừu tượng Ví dụ trên, phương thức trừu tượng DrawWindow() của lớp trừu tượng Window được lớp ListBox kế thừa. Như vậy, các lớp sau này kế thừa từ lớp ListBox đều phải thực hiện lại phương thức DrawWindow(), đây là điểm giới hạn của lớp trừu tượng. Hơn nữa, như thế sau này không bao giờ ta tạo được lớp Window đúng nghĩa. Do vậy, nên chuyển lớp trừu tượng thành giao diện trừu tượng.