1. Tính đa hình là gì
Đa hình (polymorphism
) hiểu theo cách thông thường là đa dạng, phong phú, nhiều kiểu, nhiều hình thái.
Polymorphism được cấu tạo từ 2 từ Hy Lạp: poly và morphs. Trong đó poly có nghĩa là nhiều và morphs có nghĩa là hình thái.
Trong lập trình C#, tính đa hình được hiểu là hiện tượng các đối tượng thuộc các lớp khác nhau, thực hiện cùng một hành động bằng các cách khác nhau.
Ví dụ ta có 3 loài vật là chó, lợn và mèo. 3 loài đều có tiếng kêu nhưng mỗi loài lại có tiếng kêu riêng, chó thì sủa “gâu gâu”, lợn thì kêu “éc éc”, mèo thì kêu “meo meo”. Cùng là hành động kêu nhưng mỗi loài lại thực hiện theo các cách khác nhau.
Lưu ý: Các lớp phải là con của cùng 1 lớp cha.
2. Sử dụng tính đa hình
– Tính đa hình chỉ được thể hiện khi đã ghi đè lên phương thức của lớp cha.
– Chỉ có thể ghi đè lên phương thức virtual hoặc abstract
Cách khai báo:
– Để khai báo 1 phương thức ảo bạn sử dụng từ khóa virtual.
– Để ghi đè lên phương thức của lớp cha, bạn sử dụng từ khóa override.
Ví dụ: Mình tạo ra 1 lớp Animal và 2 lớp con là Cat và Dog. Các lớp đều có hàm Speak.
namespace
da_hinh {class
Animal {public virtual void
Speak() {Console
.WriteLine("Dong vat keu ......"
); } }class
Cat :Animal
{public override void
Speak() {Console
.WriteLine("Meo keu meo meo"
); } }class
Dog :Animal
{public void
Speak() {Console
.WriteLine("Cho keu gau gau"
); } }class
Program {static void
Main(string
[] args) {Animal
Cat1 =new
Cat(); Cat1.Speak();Animal
Dog1 =new
Dog(); Dog1.Speak();Console
.ReadLine(); } } }
Ở đây mình không khởi tạo
Cat Cat1 = new Cat
mà là
Animal Cat = new Cat
.
Hàm Speak ở lớp Animal mình có khai báo virtual, hàm Speak của lớp Cat có khai báo override còn ở lớp Dog thì không.
Kết quả
Hàm Speak của lớp Dog không có override nên chương trình chạy hàm của lớp cha.
Đồng nghĩa với việc nếu mình không khai báo virtual ở lớp cha, không có override ở lớp con thì chương trình sẽ in ra màn hình 2 dòng Dong vat keu ……
3. Lớp trừu tượng
Tiếp tục xét ví dụ trên, các bạn có thấy, tại lớp cha Animal, việc gì ta phải mất công chạy lệnh Console.WriteLine trong hàm Speak. Vì đến lớp con, hàm đó lại bị ghi đè bằng hàm riêng của lớp con. Bạn có thể bỏ trống phần nội dung thân hàm Speak, kết quả vẫn ra tương tự.
Phần định nghĩa bên trong thân hàm chỉ là hình thức, thay vì như vậy bạn có thể khai báo lớp trừu tượng cho lớp Animal, khai báo hàm trừu tượng cho hàm Speak trong lớp Animal và không cần định nghĩa bên trong hàm.
Để khai báo 1 lớp trừu tượng hoặc 1 phương thức trừu tượng ta dùng từ khóa
abstract
namespace
da_hinh {abstract class
Animal {public abstract void
Speak(); }class
Cat :Animal
{public override void
Speak() {Console
.WriteLine("Meo keu meo meo"
); } }class
Dog :Animal
{public override void
Speak() {Console
.WriteLine("Cho keu gau gau"
); } }class
Program {static void
Main(string
[] args) {Animal
Cat1 =new
Cat(); Cat1.Speak();Animal
Dog1 =new
Dog(); Dog1.Speak();Console
.ReadLine(); } } }
Kết quả
Kết quả này cũng giống như khi mình khai báo hàm virtual.
Lưu ý:
Khi kế thừa 1 lớp trừu tượng bạn bắt buộc phải override tất cả các phương thức trừu tượng nhằm đảm bảo tính hợp lệ cho chương trình.