C C# Polymorphism Explained: The Hidden Pitfall of Method Hiding vs Overriding

C# Polymorphism Explained: The Hidden Pitfall of Method Hiding vs Overriding

Polymorphism is one of the core principles of object-oriented programming — and C# gives you powerful tools to work with it. But there's a subtle trap many developers fall into when dealing with method hiding vs method overriding.

Let’s break down this C# challenge to understand what’s really happening and why the output might surprise you.

 


 

👇 The Challenge:

public class Animal  // Base class (parent) 
{
    public virtual void animalSound() 
    {
        Console.WriteLine("The animal makes a sound - #");
    }
}

class Pig : Animal  // Derived class (child) 
{
    public override void animalSound() 
    {
        Console.WriteLine("The pig says: wee wee - #");
    }
}

class Dog : Animal  // Derived class (child) 
{
    public void animalSound()  // method hiding, not overriding
    {
        Console.WriteLine("The dog says: bow wow - #");
    }
}

class Program 
{
    public static void Main(string[] args) 
    {
        Animal myAnimal = new Animal();
        Animal myPig = new Pig();
        Animal myDog = new Dog();

        myAnimal.animalSound();
        myPig.animalSound();
        myDog.animalSound();
    }
}

🔍 Predict the Output

Let’s go through it line by line:

1️⃣ myAnimal.animalSound();

  • Direct call to the base method.

  • ✅ Output:

The animal makes a sound - #

2️⃣ myPig.animalSound();

  • Object is of type Pig, which overrides the base method.

  • ✅ Output:

The pig says: wee wee - #

3️⃣ myDog.animalSound();

  • Object is of type Dog, but declared as Animal.

  • Dog has a method named animalSound, but it’s not overriding the base method.

  • So the base class method is called, because C# uses the reference type here.

  • ✅ Output:

The animal makes a sound - #

✅ Final Output:

 
The animal makes a sound - #
The pig says: wee wee - #
The animal makes a sound - #

🎯 Lesson Learned

This challenge demonstrates the key difference between method overriding and method hiding.

💡 Key Takeaways

  1. Method Overriding (virtual + override) = true polymorphism

    • Decided at runtime based on the actual object type.

  2. Method Hiding (new keyword or no keyword) = depends on reference type

    • If the method is not marked override, the base method is called when accessed through a base reference.

  3. Use override intentionally

    • If you intend to replace base behavior, always use override (and declare base method as virtual or abstract).

  4. Avoid confusion

    • Method hiding can lead to unexpected and inconsistent behavior — it’s usually better to override unless you have a strong reason not to.


🧠 Real-World Example

Let’s say you have a system with a collection of Animal objects, and you want to play their sound:

List<Animal> zoo = new List<Animal> { new Pig(), new Dog(), new Animal() };
foreach (var animal in zoo)
{
    animal.animalSound();  // Dog won't say "bow wow" unless overridden
}

If you don’t override, your program won’t behave as expected — even though Dog has a method with the same name.


💬 Takeaway

This is more than an academic challenge — it’s something you’ll encounter in real-world enterprise apps, plugin frameworks, and API design. Make sure you understand how your objects behave when polymorphism is in play.

Have you ever run into this pitfall before? How do you approach polymorphism in your C# projects? Drop a comment..

 


 
 

Add comment