Nội dung chính
Tính kế thừa trong C#
Tính kế thừa (Inheritance) trong C# là một trong những khái niệm quan trọng nhất trong lập trình hướng đối tượng C#. Tính kế thừa cho phép chúng ta định nghĩa một lớp trong điều kiện một lớp khác, mà làm cho nó dễ dàng hơn để tạo và duy trì một ứng dụng. Điều này cũng cung cấp một cơ hội để tái sử dụng tính năng code và thời gian thực thi nhanh hơn.
Khi tạo một lớp, thay vì viết toàn bộ các thành viên dữ liệu và các hàm thành viên mới, lập trình viên có thể nên kế thừa các thành viên của một lớp đang tồn tại. Lớp đang tồn tại này được gọi là Base Class - lớp cơ sở, và lớp mới được xem như là Derived Class – lớp thừa kế.
Ý tưởng của tính kế thừa triển khai mối quan hệ IS-A (Là Một). Ví dụ, mammal IS A animal, dog IS-A mammal, vì thế dog IS-A animal, và ....
Lớp cơ sở (Base Class) và Lớp thừa kế (Derived Class) trong C#
Một lớp có thể được kế thừa từ hơn một lớp khác, nghĩa là, nó có thể kế thừa dữ liệu và hàm từ nhiều Lớp hoặc Interface cơ sở.
Cú pháp để tạo lớp kế thừa trong C# là:
<acess-specifier> class <base_class> { ... } class <derived_class> : <base_class> { ... }
Xét một lớp cơ sở Shape và lớp kế thừa Rectangle sau: tạo 3 lớp có tên lần lượt là Shape, HinhChuNhat, TestCsharp trong đó:
Lớp Shape là lớp cơ sở
using System; namespace KienThucLapTrinhCsharp { class Shape { protected int chieu_rong; protected int chieu_cao; public void setChieuRong(int w) { chieu_rong = w; } public void setChieuCao(int h) { chieu_cao = h; } } }
Lớp HinhChuNhat là lớp kế thừa
using System; namespace KienThucLapTrinhCsharp { class HinhChuNhat : Shape { public int tinhDienTich() { return (chieu_cao * chieu_rong); } } }
Lớp TestCsharp chứa phương thức main() để thao tác trên đối tượng HinhChuNhat
using System; namespace KienThucLapTrinhCsharp { public class TestCsharp { public static void Main(string[] args) { Console.WriteLine("Tinh ke thua trong C#"); Console.WriteLine("------------------------\n"); //tao doi tuong HinhChuNhat HinhChuNhat hcn = new HinhChuNhat(); hcn.setChieuRong(5); hcn.setChieuCao(7); // in dien tich cua doi tuong. Console.WriteLine("Dien tich hinh chu nhat: {0}", hcn.tinhDienTich()); Console.ReadKey(); } } }
Nếu bạn không sử dụng lệnh Console.ReadKey(); thì chương trình sẽ chạy và kết thúc luôn (nhanh quá đến nỗi bạn không kịp nhìn kết quả). Lệnh này cho phép chúng ta nhìn kết quả một cách rõ ràng hơn.
Biên dịch và chạy chương trình C# trên sẽ cho kết quả sau:
Khởi tạo Lớp cơ sở (Base Class) trong C#
Lớp kế thừa (Derived Class) trong C# kế thừa các biến thành viên và các phương thức thành viên từ lớp cơ sở. Vì thế, đối tượng của lớp cha nên được tạo trước khi lớp phụ được tạo. Bạn có thể cung cấp các chỉ thị để khởi tạo lớp phụ trong danh sách khởi tạo thành viên.
Chương trình ví dụ sau minh họa cách khởi tạo Lớp cơ sở (Base Class) trong C#: tạo 3 lớp có tên lần lượt là HinhChuNhat, ChiPhiXayDung, TestCsharp như sau:
Lớp HinhChuNhat là lớp cơ sở
using System; namespace KienThucLapTrinhCsharp { class HinhChuNhat { //cac bien thanh vien protected double chieu_dai; protected double chieu_rong; // constructor public HinhChuNhat(double l, double w) { chieu_dai = l; chieu_rong = w; } //phuong thuc public double tinhDienTich() { return chieu_dai * chieu_rong; } public void Display() { Console.WriteLine("Chieu dai: {0}", chieu_dai); Console.WriteLine("Chieu rong: {0}", chieu_rong); Console.WriteLine("Dien tich: {0}", tinhDienTich()); } } }
Lớp ChiPhiXayDung kế thừa lớp HinhChuNhat
using System; namespace KienThucLapTrinhCsharp { class ChiPhiXayDung : HinhChuNhat { private double COST = 80; public ChiPhiXayDung(double l, double w) : base(l, w) { } public double tinhChiPhi() { double chi_phi; chi_phi = tinhDienTich() * COST; return chi_phi; } public void hienThiThongTin() { base.Display(); Console.WriteLine("Chi phi: {0}", tinhChiPhi()); } } }
Lớp TestCsharp chứa phương thức main() để thao tác trên đối tượng ChiPhiXayDung
using System; namespace KienThucLapTrinhCsharp { public class TestCsharp { public static void Main(string[] args) { Console.WriteLine("Tinh ke thua trong C#"); Console.WriteLine("Khoi tao lop co so"); Console.WriteLine("------------------------\n"); //tao doi tuong ChiPhiXayDung ChiPhiXayDung t = new ChiPhiXayDung(6, 9); t.hienThiThongTin(); Console.ReadLine(); Console.ReadKey(); } } }
Biên dịch và chạy chương trình C# trên sẽ cho kết quả sau:
Đa kế thừa trong C#
C# không hỗ trợ đa kế thừa. Tuy nhiên, bạn có thể sử dụng Interface để triển khai đa kế thừa. Ví dụ sau minh họa cách sử dụng Interface để triển khai đa kế thừa trong C#: chúng ta tạo 2 lớp có tên lần lượt là Shape, HinhChuNhat, TestCsharp và một interface có tên là ChiPhiSon như sau:
Lớp Shape là lớp cơ sở
using System; namespace KienThucLapTrinhCsharp { class Shape { protected int chieu_rong; protected int chieu_cao; public void setChieuRong(int w) { chieu_rong = w; } public void setChieuCao(int h) { chieu_cao = h; } } }
interface ChiPhiSon
using System; namespace KienThucLapTrinhCsharp { public interface ChiPhiSon { int tinhChiPhi(int dien_tich); } }
Lớp HinhChuNhat là lớp kế thừa lớp Shape và interface ChiPhiSon
using System; namespace KienThucLapTrinhCsharp { class HinhChuNhat : Shape, ChiPhiSon { public int tinhDienTich() { return (chieu_rong * chieu_cao); } public int tinhChiPhi(int dien_tich) { return dien_tich * 80; } } }
Lớp TestCsharp chứa phương thức main() để thao tác trên đối tượng HinhChuNhat
using System; namespace KienThucLapTrinhCsharp { public class TestCsharp { public static void Main(string[] args) { Console.WriteLine("Tinh ke thua trong C#"); Console.WriteLine("Vi du minh hoa Da ke thua"); Console.WriteLine("------------------------------"); //tao doi tuong HinhChuNhat HinhChuNhat hcn = new HinhChuNhat(); int dien_tich; hcn.setChieuRong(6); hcn.setChieuCao(9); dien_tich = hcn.tinhDienTich(); // in dien tich va chi phi. Console.WriteLine("Tong dien tich: {0}", hcn.tinhDienTich()); Console.WriteLine("Tong chi phi son: {0}", hcn.tinhChiPhi(dien_tich)); Console.ReadLine(); Console.ReadKey(); } } }
Biên dịch và chạy chương trình C# trên sẽ cho kết quả sau: