Computer >> บทช่วยสอนคอมพิวเตอร์ >  >> การเขียนโปรแกรม >> C#

ความแตกต่างระหว่าง Overriding และ Hiding (Shadowing) ใน C#

Overriding vs Hiding (Shadowing) ใน C#

ทั้งสองเกี่ยวกับการนิยามเมธอดใน Derived Class ที่มีชื่อเหมือน Base Class แต่วัตถุประสงค์และพฤติกรรมต่างกัน

Overriding (การเขียนทับ) - ใช้ virtual/override

  • Base class ต้องระบุ virtual (หรือ abstract)
  • Derived class ใช้ override
  • **Polymorphism ทำงาน**: เรียกผ่าน Base reference ให้เมธอด Derived ทำงาน
  • สามารถเข้าถึง Base implementation ได้ด้วย base.Method()

class Animal
{
    public virtual void Speak() => Console.WriteLine("Animal sound");
}

class Dog : Animal
{
    public override void Speak() => Console.WriteLine("Woof!");
}

// ใช้งาน
Animal a = new Dog();
a.Speak(); // "Woof!" - Polymorphism ทำงาน

Hiding/Shadowing (การซ้อนเงา) - ใช้ new

  • Base class **ไม่ต้อง** มี virtual
  • Derived class ใช้ new (warning ถ้าไม่ใส่)
  • **ไม่มี Polymorphism**: เรียกผ่าน Base reference ให้ Base method ทำงาน
  • Derived class มี implementation ของตัวเองแยกต่างหาก

class Animal
{
    public void Speak() => Console.WriteLine("Animal sound");
}

class Dog : Animal
{
    public new void Speak() => Console.WriteLine("Woof!");
}

// ใช้งาน
Animal a = new Dog();
a.Speak();        // "Animal sound" - Base method!
Dog d = new Dog();
d.Speak();        // "Woof!" - Derived method

ตารางเปรียบเทียบ

คุณสมบัติOverridingHiding (Shadowing)
Base class keywordvirtual / abstractไม่จำเป็น (ปกติ)
Derived class keywordoverridenew
Polymorphism✅ ทำงาน❌ ไม่ทำงาน
เข้าถึง Base methodbase.Method()ไม่ได้โดยตรง (ต้อง cast)
Compiler warningไม่มี (ถูกต้อง)มี (ถ้าไม่ใส่ new)
วัตถุประสงค์ขยาย/เปลี่ยนพฤติกรรมแทนที่/ซ่อน implementation

ตัวอย่างครบ: เปรียบเทียบพร้อมกัน


using System;

class Base
{
    public virtual void VirtualMethod() => Console.WriteLine("Base.Virtual");
    public void NormalMethod() => Console.WriteLine("Base.Normal");
}

class Derived : Base
{
    public override void VirtualMethod() => Console.WriteLine("Derived.Virtual (Override)");
    public new void NormalMethod() => Console.WriteLine("Derived.Normal (Hiding)");
}

class Program
{
    static void Main()
    {
        Base b = new Derived();
        Derived d = new Derived();

        Console.WriteLine("=== ผ่าน Base reference ===");
        b.VirtualMethod(); // Derived.Virtual (Override) - Polymorphism
        b.NormalMethod();  // Base.Normal - No polymorphism

        Console.WriteLine("\n=== ผ่าน Derived reference ===");
        d.VirtualMethod(); // Derived.Virtual
        d.NormalMethod();  // Derived.Normal (Hiding)
    }
}

ผลลัพธ์


=== ผ่าน Base reference ===
Derived.Virtual (Override)
Base.Normal

=== ผ่าน Derived reference ===
Derived.Virtual (Override)
Derived.Normal (Hiding)

เมื่อไหร่ควรใช้อะไร?

  • Override: ต้องการ Polymorphism, ขยายพฤติกรรม Base, Liskov Substitution Principle
  • Hiding (new): Base class ไม่ได้ design ให้ override, ต้องการ interface ใหม่ทั้งหมด, Versioning (base เพิ่มเมธอดใหม่ชนกับ derived)

Sealed Override - ป้องกัน Override เพิ่ม


class Base { public virtual void M() { } }
class Middle : Base { public sealed override void M() { } } // ไม่ให้ override ต่อ
class Derived : Middle { /* public override void M() { } */ } // ❌ Compile error