Tính đa hình (Polymophysm)
Tính đa hình
Đa hình hiểu theo định nghĩa trong từ điển là một nguyên tắc trong sinh học, trong đó các sinh vật cùng một nhóm hay loài có thể có hình thức, hình dạng khác nhau hoặc cùng một hành vi nhưng lại có cách thể hiện khác nhau. Minh hoạ sau giúp ta hiểu hơn tính đa hình trong đời sống thực:
Như vậy bạn thấy đó, cùng là loài bướm nhưng các loại bướm khác nhau sẽ có hình dáng và màu sắc khác nhau. Ngoài ra dù cho con người hay các loài động vật đều có nguồn gốc về nhóm sinh học giống nhau nhưng hình thái hay là hành động lại thể hiện khác nhau.
Như chúng ta đã biết mô hình lập trình hướng đối tượng là cố gắng để có được mô hình lập trình thể hiện tốt nhất được bản chất của các đối tượng trong tự nhiên nên tính đa hình cũng có thể được áp dụng cho lập trình hướng đối tượng của C#. Các lớp con sau khi thừa kế tới lớp cha thì có thể dùng lại các đặc tính và hành động của lớp cha những cũng có thể định nghĩa các hành vi riêng của mình tạo nên sự khác biệt so với lớp cha và cả các lớp con khác.
Loại đa hình
Đa hình trong C# có 2 loại: đa hình thời gian dịch (compile time polymorphism) và đa hình trong lúc chạy (runtime polymorphism). Sự khác nhau của 2 loại này chính là quá trình đa hình được thực hiện trong lúc dịch hay lúc chạy mã lệnh liên quan. Minh hoạ sau sẽ giúp bạn rõ hơn về các loại thể hiện đa hình trong lập trình C#:
Nạp chồng phương thức (Method Overloading)
Trong C#, đa hình lúc dịch được thực hiện thông qua quá trình nạp chồng phương thức. Điều đó có nghĩa là tính đa hình được thể hiện trong 1 lớp bạn có thể tạo các phương thức hoặc phương thức khởi tạo có cùng tên nhưng khác nhau số lượng và kiểu tham số. Mỗi phương thức này có thể có nội dung khác nhau nhưng thường vẫn hướng vào một múc đích chung.
Ví dụ CompileTimePolymorphysmDemo sau đây sẽ làm rõ hơn về loại đa hình trong lúc dịch này:
Ghi đè phương thức (Method Overriding)
Ghi đè phương thức được coi là cách thức hoàn hảo trong quá trình triển khai đa hình trong C#. Khi đó, lớp con mà thừa kế tới lớp cha thì có thể quyết định là dùng lại các phương thức của lớp cha hay là ghi đè nội dung mới lên nội dung của phương thức thuộc lớp cha. Như vậy, khi có nhiều lớp con thừa kế đến 1 lớp cha thì mỗi lớp con sẽ có khả năng tạo ra những phương thức hoạt động khác nhau thông qua ghi đè phương thức. Tiếp tục ví dụ CarDemo ở trên, chúng ta sẽ cập nhật các lớp như sau:
using System; namespace RuntimePolymorphysmDemo { public class Car { public string make; public string model; public string color; public string vin; public Car(string _make, string _model, string _color, string _vin) { this.make = _make; this.model = _model; this.color = _color; this.vin = _vin; } public void Start() { Console.WriteLine("Car is starting!"); } public void Stop() { Console.WriteLine("Car is stopped!"); } public void PrintDescription() { Console.WriteLine("Car is " + this.model + " of " + this.make + " with " + this.color + "color and VIN: " + this.vin); } } }
Sau đó xin mời bạn tạo thêm phương thức PrintDescription()
ở 3 lớp tương ứng lần lượt là Sedan
, Convertible
và Electric
:
using System; namespace RuntimePolymorphysmDemo { public class Sedan : Car { double speed; public Sedan(string _make, string _model, string _color, string _vin) : base(_make, _model, _color, _vin) { } public void Boost(double _increase) { this.speed += _increase; } public void PrintDescription() { Console.WriteLine("Sedan is " + this.model + " of " + this.make + " with " + this.color + " color and VIN: " + this.vin); } } }
using System; namespace RuntimePolymorphysmDemo { public class Convertible : Car { public Convertible(string _make, string _model, string _color, string _vin) : base(_make, _model, _color, _vin) { } public void OpenTop() { Console.WriteLine("Car is opening top!"); } public void PrintDescription() { Console.WriteLine("Convertible is " + this.model + " of " + this.make + " with " + this.color + " color and VIN:" + this.vin); } } }
using System; namespace RuntimePolymorphysmDemo { public class Electric : Car { public Electric(string _make, string _model, string _color, string _vin) : base(_make, _model, _color, _vin) { } public void Charge() { Console.WriteLine("Car is charging!"); } public void printDescription() { Console.WriteLine("Electric is " + this.model + " of " + this.make + " with " + this.color + " color and VIN: " + this.vin); } } }
Cuối cùng trong lớp chính của ứng dụng CarDemo, xin mời bạn gõ đoạn mã lệnh sau:
using System; namespace RuntimePolymorphysmDemo { public class Program { public static void Main(string[] args) { Sedan car1 = new Sedan("Toyota", "Carmy", "Black", "TCB00001"); car1.PrintDescription(); Convertible car2 = new Convertible("Mercedes-Benz", "C3000", "Red", "MCR00001"); car2.PrintDescription(); Electric car3 = new Electric("Nissan", "Leaf", "Red", "NLR00001"); car3.PrintDescription(); } } }
Ví dụ RuntimePolymorphysmDemo sau đây sẽ minh hoạ cụ thể cách sử dụng kỹ thuật đa hình lúc chạy: