VieLang
ITTiếng Anh
  • Góc học tập
Tải app
  • Thư viện
  • Luyện thi
  • Cẩm nang
  • Góc học tập
OOP và thiết kếBốn trụ cột OOP
Bài 2/12
5 phút

Kế thừa

Nội dung bài · 5 mục
  1. 1.Khái niệm
  2. 2.Ví dụ
  3. 3.Thử ngay
  4. 4.Lỗi hay gặp
  5. 5.Tóm tắt

Cửa hàng bán sách giấy và ebook. Cả hai đều có tên, có giá, có cùng cách hiển thị. Viết hai class riêng thì phần chung bị lặp lại, sửa một chỗ lại phải nhớ sửa chỗ kia. Kế thừa giải quyết đúng việc này.

Khái niệm

🧬 Kế thừa (inheritance): class con nhận lại field, property và method của class cha, rồi thêm phần riêng của mình.

👪 Class cha, class con (base class, derived class): class được kế thừa là class cha, class kế thừa nó là class con, khai báo bằng class Con : Cha.

Kế thừa chỉ đúng khi class con là một loại của class cha. Sách giấy là một loại sản phẩm, nên PhysicalProduct : Product hợp lý.

Ví dụ

var book = new PhysicalProduct("Sách C#", 150000, 800);
Console.WriteLine(book.Describe());
Console.WriteLine(book.ShippingFee());

class Product
{
    public string Name { get; }
    public decimal Price { get; }

    public Product(string name, decimal price)
    {
        Name = name;
        Price = price;
    }

    public string Describe()
    {
        return $"{Name} - {Price}đ";
    }
}

class PhysicalProduct : Product
{
    public int WeightGram { get; }

    public PhysicalProduct(
        string name, decimal price, int weightGram)
        : base(name, price)
    {
        WeightGram = weightGram;
    }

    public decimal ShippingFee()
    {
        return WeightGram * 10;
    }
}
  • book dùng được Name, Price, Describe() dù PhysicalProduct không khai báo chúng. Tất cả nhận lại từ Product.
  • WeightGram và ShippingFee() là phần riêng, chỉ class con có.
  • Constructor không được kế thừa. : base(name, price) gọi constructor của Product để gán Name và Price, rồi class con gán tiếp WeightGram.
  • Một class chỉ kế thừa được một class cha.
Product + Name: string + Price: decimal + Describe(): string PhysicalProduct + WeightGram: int + ShippingFee(): decimal
PhysicalProduct nhận lại phần của Product, chỉ khai báo thêm phần riêng

Thử ngay

Chép ví dụ trên vào Program.cs. Thay ba dòng đầu bằng các lệnh gọi dưới đây, rồi thêm class DigitalProduct vào cuối file:

var ebook = new DigitalProduct(
    "Ebook C#", 90000, "https://shop.vn/ebook");

Console.WriteLine(ebook.Describe());
Console.WriteLine(ebook.DownloadUrl);

class DigitalProduct : Product
{
    public string DownloadUrl { get; }

    public DigitalProduct(
        string name, decimal price, string downloadUrl)
        : base(name, price)
    {
        DownloadUrl = downloadUrl;
    }
}

Đoán trước khi chạy: DigitalProduct không hề khai báo Describe(). Dòng ebook.Describe() có chạy được không, và in ra gì?

Xem kết quả
Ebook C# - 90000đ
https://shop.vn/ebook

Chạy được. DigitalProduct kế thừa Describe() từ Product, nên phần chung chỉ viết một lần ở class cha.

Lỗi hay gặp

Quên gọi base(...). Class cha không có constructor rỗng thì compiler không biết tạo phần cha bằng cách nào (như bài Property và constructor: có constructor nhận tham số thì không còn constructor rỗng).

// SAI — lỗi compile: thiếu base(name, price)
class GiftCard : Product
{
    public GiftCard(string name, decimal price)
    {
    }
}
// ĐÚNG
class GiftCard : Product
{
    public GiftCard(string name, decimal price)
        : base(name, price)
    {
    }
}

Kế thừa chỉ để dùng lại code. Khách hàng không phải là một địa chỉ, nên Customer : Address là sai, dù làm vậy giúp Customer có sẵn Street.

// SAI — khách hàng không "là một" địa chỉ
class Customer : Address
{
    public string Name { get; set; } = "";
}

class Address
{
    public string Street { get; set; } = "";
}
// ĐÚNG — khách hàng "có một" địa chỉ
class Customer
{
    public string Name { get; set; } = "";
    public Address Address { get; set; }
        = new Address();
}

Tóm tắt

  • class Con : Cha: class con nhận lại property và method của class cha, rồi thêm phần riêng.
  • Constructor không được kế thừa. Class con gọi constructor của cha bằng : base(...).
  • Một class chỉ có một class cha.
  • Chỉ kế thừa khi con là một loại của cha.

Tự kiểm tra

0/3 câu
Câu 1

Class Employee có method GetInfo(). Class Manager : Employee không khai báo gì thêm. Gọi new Manager(...).GetInfo() thì sao?

Câu 2

Class Vehicle chỉ có constructor Vehicle(string plate). Class Truck : Vehicle viết constructor Truck(string plate) { } mà không có : base(plate). Chuyện gì xảy ra?

Câu 3

Trường hợp nào dùng kế thừa là hợp lý?

Đóng góiĐa hình

Nội dung bài

  1. 1.Khái niệm
  2. 2.Ví dụ
  3. 3.Thử ngay
  4. 4.Lỗi hay gặp
  5. 5.Tóm tắt