Bài 1: Giới thiệu về Trình quản lý quảng cáo
Tính Đa Hình (Polymorphism) trong C#
1. Tính đa hình là gì?
Tính đa hình là khả năng một phương thức có thể hoạt động khác nhau tùy thuộc vào đối tượng cụ thể. Trong C#, có 2 loại đa hình chính:
- Đa hình thời gian biên dịch (Compile-time polymorphism) – Thể hiện qua method overloading.
- Đa hình thời gian chạy (Runtime polymorphism) – Thể hiện qua method overriding, interface, và lớp trừu tượng (abstract class).
2. Đa hình thời gian biên dịch (Method Overloading)
- Cùng một phương thức nhưng có thể có nhiều phiên bản với tham số khác nhau.
- Việc gọi phương thức nào sẽ được xác định tại thời điểm biên dịch.
Ví dụ:
using System;
class MayTinh
{
public int TinhTong(int a, int b)
{
return a + b;
}
public double TinhTong(double a, double b)
{
return a + b;
}
public int TinhTong(int a, int b, int c)
{
return a + b + c;
}
}
class Program
{
static void Main()
{
MayTinh mt = new MayTinh();
Console.WriteLine(mt.TinhTong(2, 3)); // Output: 5
Console.WriteLine(mt.TinhTong(2.5, 3.5)); // Output: 6.0
Console.WriteLine(mt.TinhTong(1, 2, 3)); // Output: 6
}
}
📌 Ghi nhớ:
- C# hỗ trợ nạp chồng phương thức (Method Overloading), nhưng phải khác nhau về danh sách tham số (số lượng, kiểu dữ liệu).
- Không thể nạp chồng chỉ dựa vào kiểu trả về.
3. Đa hình thời gian chạy (Method Overriding)
- Khi một lớp con ghi đè (override) một phương thức của lớp cha.
- Dùng từ khóa virtual trong lớp cha và override trong lớp con.
- Việc chọn phương thức nào để gọi được quyết định khi chương trình chạy (runtime).
Ví dụ:
using System;
class DongVat
{
public virtual void Keu()
{
Console.WriteLine("Động vật đang kêu...");
}
}
class Cho : DongVat
{
public override void Keu()
{
Console.WriteLine("Gâu gâu!");
}
}
class Meo : DongVat
{
public override void Keu()
{
Console.WriteLine("Meo meo!");
}
}
class Program
{
static void Main()
{
DongVat dongVat1 = new Cho();
DongVat dongVat2 = new Meo();
dongVat1.Keu(); // Output: Gâu gâu!
dongVat2.Keu(); // Output: Meo meo!
}
}
📌 Ghi nhớ:
- virtual → Cho phép phương thức của lớp cha có thể bị ghi đè.
- override → Dùng trong lớp con để ghi đè phương thức của lớp cha.
- Nếu không có
override, phương thức của lớp cha sẽ được gọi.
4. Đa hình với lớp trừu tượng (Abstract Class)
- Lớp trừu tượng (abstract class) chứa các phương thức trừu tượng (abstract method) mà lớp con bắt buộc phải triển khai.
- Không thể tạo đối tượng từ lớp trừu tượng.
Ví dụ:
using System;
abstract class HinhHoc
{
public abstract double TinhDienTich();
}
class HinhTron : HinhHoc
{
public double BanKinh { get; set; }
public HinhTron(double banKinh)
{
BanKinh = banKinh;
}
public override double TinhDienTich()
{
return Math.PI * BanKinh * BanKinh;
}
}
class HinhChuNhat : HinhHoc
{
public double ChieuDai { get; set; }
public double ChieuRong { get; set; }
public HinhChuNhat(double chieuDai, double chieuRong)
{
ChieuDai = chieuDai;
ChieuRong = chieuRong;
}
public override double TinhDienTich()
{
return ChieuDai * ChieuRong;
}
}
class Program
{
static void Main()
{
HinhHoc hinh1 = new HinhTron(5);
HinhHoc hinh2 = new HinhChuNhat(4, 6);
Console.WriteLine($"Diện tích hình tròn: {hinh1.TinhDienTich()}");
Console.WriteLine($"Diện tích hình chữ nhật: {hinh2.TinhDienTich()}");
}
}
📌 Ghi nhớ:
- abstract class → Không thể tạo đối tượng, chỉ dùng để làm lớp cha.
- abstract method → Lớp con phải override và triển khai nó.
5. Đa hình với Interface
- Interface chỉ chứa khai báo phương thức, không có triển khai.
- Một lớp có thể kế thừa nhiều interface (đa kế thừa).
Ví dụ:
using System;
interface IAn
{
void An();
}
interface INoi
{
void Noi();
}
class ConNguoi : IAn, INoi
{
public void An()
{
Console.WriteLine("Con người đang ăn...");
}
public void Noi()
{
Console.WriteLine("Con người đang nói...");
}
}
class Program
{
static void Main()
{
ConNguoi nguoi = new ConNguoi();
nguoi.An();
nguoi.Noi();
}
}
📌 Ghi nhớ:
- Interface chỉ có khai báo, không có nội dung phương thức.
- Một lớp có thể triển khai nhiều interface, giúp đa kế thừa linh hoạt hơn.
Tổng kết
| Phương pháp | Đặc điểm |
|---|---|
| Method Overloading | Đa hình biên dịch (compile-time) |
| Method Overriding | Đa hình thời gian chạy (runtime) |
| Abstract Class | Dùng khi có phương thức cần triển khai bắt buộc cho lớp con |
| Interface | Định nghĩa hành vi chung, một lớp có thể kế thừa nhiều interface |
🔥 Tóm lại: Đa hình giúp code linh hoạt hơn, dễ mở rộng, và hỗ trợ nguyên tắc Lập trình hướng đối tượng (OOP).
Bạn có muốn thêm bài tập không? 😊
Viết chương trình C# sử dụng đa hình (Polymorphism) để quản lý nhân sự trong một công ty. Chương trình gồm các lớp sau:
-
Lớp cha
NhanVien(abstract class) có:- Thuộc tính:
HoTen,LuongCoBan. - Phương thức trừu tượng
TinhLuong(), yêu cầu lớp con phải override.
- Thuộc tính:
-
Lớp con
NhanVienFullTimekế thừaNhanVien:- Có thêm thuộc tính
HeSoLuong. - Override phương thức
TinhLuong()theo công thức: Luong=LuongCoBan×HeSoLuongLuong = LuongCoBan \times HeSoLuongLuong=LuongCoBan×HeSoLuong
- Có thêm thuộc tính
-
Lớp con
NhanVienPartTimekế thừaNhanVien:- Có thêm thuộc tính
SoGioLam,LuongMoiGio. - Override phương thức
TinhLuong()theo công thức: Luong=SoGioLam×LuongMoiGioLuong = SoGioLam \times LuongMoiGioLuong=SoGioLam×LuongMoiGio
- Có thêm thuộc tính
-
Lớp
Program- Nhập danh sách nhân viên (Full-time và Part-time).
- Hiển thị thông tin nhân viên cùng mức lương tương ứng.