uocmo_kchodoi
Moderator
- Xu
- 132
TÍNH ĐA HÌNH (POLYMORPHISM) TRONG C#
Khái niệm: Đa hình có nhiều hình thức về nghĩa. Trong mô hình lập trình hướng đối tượng, đa hình thường được hiểu là “một giao diện, nhiều chức năng”.
Đa hình có thể là tĩnh hoặc động. Trong đa hình tĩnh, sự đáp lại với một chức năng được xác định tại thời gian biên dịch. Trong đa hình năng động, nó được quyết định tại thời gian chạy.
Tính đa hình trong C# có thể là static hoặc dynamic. Trong đó, kiểu đa hình static có thể được gọi là đa hình tĩnh và kiểu đa hình dynamic có thể được gọi là đa hình động.
Trong đa hình tĩnh, phần phản hồi tới một hàm được xác định tại compile time. Trong khi đó với đa hình động, nó được quyết định tại runtime.
1. Đa hình static trong C#
Kỹ thuật liên kết một hàm với một đối tượng trong thời gian biên dịch được gọi là Early Binding. Nó cũng được gọi là Static Binding. C# cung cấp hai kỹ thuật để triển khai đa hình tĩnh. Chúng là:
- Nạp chồng hàm (Function overloading)
- Nạp chồng toán tử (Operator overloading)
2. Nạp chồng hàm trong C#
Bạn có thể có nhiều định nghĩa cho cùng tên hàm trong cùng một phạm vi. Các định nghĩa này của hàm phải khác nhau: như kiểu và/hoặc số tham số trong danh sách tham số. Trong C#, bạn không thể nạp chồng các khai báo hàm mà chỉ khác nhau ở kiểu trả về.
Ví dụ sau minh họa cách sử dụng hàm print() để in các kiểu dữ liệu khác nhau trong C#:
using System;
namespace VietJackCsharp
{
public class TestCsharp
{
void print(int i)
{
Console.WriteLine("In so nguyen: {0}", i);
}
void print(double f)
{
Console.WriteLine("In so thuc: {0}", f);
}
void print(string s)
{
Console.WriteLine("In chuoi: {0}", s);
}
static void Main(string[] args)
{
Console.WriteLine("Tinh da hinh trong C#");
Console.WriteLine("--------------------------");
//tao doi tuong TestCsharp
TestCsharp p = new TestCsharp();
// goi ham print()
p.print(5);
p.print(500.263);
p.print("Hoc C# co ban va nang cao");
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:
C# cho phép bạn tạo các lớp abstract (trừu tượng) mà được sử dụng để cung cấp trình triển khai cục bộ lớp của một Interface. Trình triển khai (Implementation) được hoàn thành khi một lớp kế thừa kế thừa từ nó. Các lớp Abstract chứa các phương thức abstract, mà được triển khai bởi lớp kế thừa. Lớp kế thừa này có tính năng chuyên dụng hơn.
Dưới đây là một số qui tắc về các lớp abstract trong C#:
- Bạn không thể tạo một Instance (sự thể hiện) của một lớp abstract.
- Bạn không thể khai báo một phương thức abstract ở bên ngoài một lớp abstract.
- Khi một lớp được khai báo là sealed, nó không thể được kế thừa, các lớp abstract không thể được khai báo là sealed.
Lớp Shape: là một lớp abstract
using System;
namespace VietJackCsharp
{
abstract class Shape
{
public abstract int tinhDienTich();
}
}
Lớp HinhChuNhat: là một lớp kế thừa lớp Shape
using System;
namespace VietJackCsharp
{
class HinhChuNhat : Shape
{
private int chieu_dai;
private int chieu_rong;
public HinhChuNhat(int a = 0, int b = 0)
{
chieu_dai = a;
chieu_rong = b;
}
public override int tinhDienTich()
{
Console.WriteLine("Dien tich hinh chu nhat:");
return (chieu_rong * chieu_dai);
}
}
}
Lớp TestCsharp: chứa phương thức main() để thao tác trên đối tượng HinhChuNhat
using System;
namespace VietJackCsharp
{
public class TestCsharp
{
static void Main(string[] args)
{
Console.WriteLine("Tinh da hinh trong C#");
Console.WriteLine("Vi du minh hoa Da hinh dong");
Console.WriteLine("--------------------------");
HinhChuNhat r = new HinhChuNhat(10, 7);
double a = r.tinhDienTich();
Console.WriteLine("Dien tich: {0}", a);
Console.ReadKey();
}
}
}
Biên dịch và chạy chương trình C# trên sẽ cho kết quả sau:
Đa hình động trong C# được triển khai bởi các lớp abstract và các hàm virtual.
Ví dụ sau minh họa điều này: tạo 5 lớp có tên lần lượt là như sau:
Lớp Shape: lớp cơ sở
using System;
namespace VietJackCsharp
{
class Shape
{
protected int chieu_rong, chieu_cao;
public Shape(int a = 0, int b = 0)
{
chieu_rong = a;
chieu_cao = b;
}
public virtual int tinhDienTich()
{
Console.WriteLine("Dien tich cua class cha: ");
return 0;
}
}
}
Lớp HinhChuNhat: là lớp kế thừa lớp Shape
using System;
namespace VietJackCsharp
{
class HinhChuNhat : Shape
{
public HinhChuNhat( int a=0, int b=0): base(a, b)
{
}
public override int tinhDienTich()
{
Console.WriteLine("Dien tich cua class HinhChuNhat: ");
return (chieu_rong * chieu_cao);
}
}
}
Lớp TamGiac: là lớp kế thừa lớp Shape
using System;
namespace VietJackCsharp
{
class TamGiac : Shape
{
public TamGiac(int a = 0, int b = 0) : base(a, b)
{
}
public override int tinhDienTich()
{
Console.WriteLine("Dien tich cua class TamGiac: ");
return (chieu_cao * chieu_rong / 2);
}
}
}
Lớp HienThiDuLieu: in các dữ liệu
using System;
namespace VietJackCsharp
{
class HienThiDuLieu
{
public void hienThiDienTich(Shape sh)
{
int a;
a = sh.tinhDienTich();
Console.WriteLine("Dien tich: {0}", a);
}
}
}
Lớp TestCsharp: chứa phương thức main() để thao tác trên các đối tượng
using System;
namespace VietJackCsharp
{
public class TestCsharp
{
static void Main(string[] args)
{
Console.WriteLine("Tinh da hinh trong C#");
Console.WriteLine("Vi du minh hoa Da hinh dong");
Console.WriteLine("--------------------------");
HienThiDuLieu c = new HienThiDuLieu();
HinhChuNhat r = new HinhChuNhat(10, 7);
TamGiac t = new TamGiac(10, 5);
c.hienThiDienTich(r);
c.hienThiDienTich(t);
Console.ReadKey();
}
}
}
Biên dịch và chạy chương trình C# trên sẽ cho kết quả sau:
Nguồn: vietjack.com