Computer >> Hướng Dẫn Máy Tính >  >> Lập Trình >> C#

Kế thừa (Inheritance) trong C#

Inheritance (Kế thừa) cho phép định nghĩa class mới (derived class) dựa trên class hiện có (base class), tái sử dụng code, mở rộng hành vi. C# hỗ trợ single inheritance cho class (chỉ kế thừa 1 base class), nhưng implement nhiều interface.

Khái niệm cốt lõi

  • Base class (Parent/Superclass): Class được kế thừa.
  • Derived class (Child/Subclass): Class kế thừa.
  • : ký hiệu kế thừa: class Derived : Base.
  • base: Truy cập member của base class.
  • virtual / override: Polymorphism.
  • sealed: Ngăn không cho kế thừa/override thêm.
  • abstract: Class/method bắt buộc override, không tạo instance.

Ví dụ: Shape → Rectangle

using System;

namespace InheritanceDemo
{
    // Base class
    class Shape
    {
        protected int Width;  // protected: derived class truy cập được
        protected int Height;
        
        public void SetWidth(int w) => Width = w;
        public void SetHeight(int h) => Height = h;
        
        // Virtual method: cho phép override
        public virtual void Display() 
            => Console.WriteLine($"Shape: {Width}x{Height}");
    }
    
    // Derived class
    class Rectangle : Shape
    {
        public int GetArea() => Width * Height;
        
        // Override virtual method
        public override void Display()
        {
            base.Display(); // Gọi base implementation
            Console.WriteLine($"Rectangle Area: {GetArea()}");
        }
    }
    
    // Derived class khác
    class Triangle : Shape
    {
        public int GetArea() => Width * Height / 2;
        
        public override void Display()
        {
            Console.WriteLine($"Triangle: {Width}x{Height}, Area: {GetArea()}");
        }
    }
    
    class Program
    {
        static void Main()
        {
            Rectangle rect = new Rectangle();
            rect.SetWidth(5);
            rect.SetHeight(7);
            rect.Display();
            
            Console.WriteLine();
            
            Triangle tri = new Triangle();
            tri.SetWidth(10);
            tri.SetHeight(6);
            tri.Display();
            
            // Polymorphism
            Console.WriteLine("\n--- Polymorphism ---");
            Shape[] shapes = { new Rectangle { Width = 3, Height = 4 }, new Triangle { Width = 5, Height = 8 } };
            foreach (var s in shapes)
                s.Display(); // Gọi override method tại runtime
        }
    }
}

Kết quả

Shape: 5x7
Rectangle Area: 35

Triangle: 10x6, Area: 30

--- Polymorphism ---
Shape: 3x4
Rectangle Area: 12
Triangle: 5x8, Area: 20

Constructor trong kế thừa

class Base
{
    public Base() { Console.WriteLine("Base()"); }
    public Base(int x) { Console.WriteLine($"Base({x})"); }
}

class Derived : Base
{
    public Derived() { Console.WriteLine("Derived()"); } // Gọi Base() ngầm
    public Derived(int x, int y) : base(x) { Console.WriteLine($"Derived({x},{y})"); } // Gọi Base(x)
}

Access Modifiers trong kế thừa

ModifierBase classDerived classOutside
public✅✅✅
protected✅✅❌
internal✅✅ (cùng assembly)✅ (cùng assembly)
protected internal✅✅✅ (cùng assembly)
private protected✅✅ (cùng assembly)❌
private✅❌❌

Best Practices

  • "Favor composition over inheritance" (GoF) - dùng interface + DI thay vì kế thừa sâu.
  • Base class nên abstract nếu không có ý nghĩa standalone.
  • Dùng sealed cho class không muốn ai kế thừa, hoặc sealed override cho method.
  • Gọi base.Constructor() tường minh khi base có parameterized constructor.