What is method hiding and how does it differ from method overriding?

12 minintermediateOOPmethod-hidingoverridingpolymorphism

Quick Answer

Method hiding uses the 'new' keyword to hide a base class method with a new implementation. Overriding uses 'override' to provide a new implementation of a virtual method. Hiding breaks polymorphism - calls are resolved at compile-time. Overriding maintains polymorphism - calls are resolved at runtime based on actual object type.

Detailed Answer

Method hiding uses the new keyword to hide a base class method, while method overriding uses the override keyword to replace a virtual method. The key difference is in when the method resolution occurs and how polymorphism behaves.

Key Differences:

AspectMethod Hiding (new)Method Overriding (override)
ResolutionCompile-timeRuntime
PolymorphismBased on reference typeBased on object type
Base MethodCannot call base methodCan call base method with base.
Virtual RequiredNo (can hide any method)Yes (must be virtual/abstract/override)
Method SignatureMust match exactlyMust match exactly

Example:

public class Animal
{
    // Virtual method - can be overridden
    public virtual void MakeSound()
    {
        Console.WriteLine("Animal makes a sound");
    }
    
    // Regular method - can be hidden
    public void Move()
    {
        Console.WriteLine("Animal moves");
    }
    
    // Virtual method for demonstration
    public virtual void Sleep()
    {
        Console.WriteLine("Animal sleeps");
    }
}

public class Dog : Animal
{
    // Method Overriding - runtime polymorphism
    public override void MakeSound()
    {
        Console.WriteLine("Dog barks: Woof!");
    }
    
    // Method Hiding - compile-time polymorphism
    public new void Move()
    {
        Console.WriteLine("Dog runs on four legs");
    }
    
    // Method Hiding with new keyword (explicit)
    public new void Sleep()
    {
        Console.WriteLine("Dog sleeps in a dog bed");
    }
}

public class Cat : Animal
{
    // Method Overriding
    public override void MakeSound()
    {
        Console.WriteLine("Cat meows: Meow!");
    }
    
    // Method Hiding
    public new void Move()
    {
        Console.WriteLine("Cat walks gracefully");
    }
    
    // Method Hiding
    public new void Sleep()
    {
        Console.WriteLine("Cat sleeps on a windowsill");
    }
}

// Demonstration of the differences
public class MethodHidingVsOverridingDemo
{
    public static void Demonstrate()
    {
        Console.WriteLine("=== Method Hiding vs Overriding Demo ===");
        
        // Create objects
        Animal animal1 = new Dog();
        Animal animal2 = new Cat();
        
        Dog dog = new Dog();
        Cat cat = new Cat();
        
        Console.WriteLine("\n--- Runtime Polymorphism (Override) ---");
        // Method resolution based on ACTUAL object type
        animal1.MakeSound(); // Calls Dog.MakeSound() - runtime polymorphism
        animal2.MakeSound(); // Calls Cat.MakeSound() - runtime polymorphism
        
        Console.WriteLine("\n--- Compile-time Polymorphism (Hiding) ---");
        // Method resolution based on REFERENCE type
        animal1.Move(); // Calls Animal.Move() - compile-time polymorphism
        animal2.Move(); // Calls Animal.Move() - compile-time polymorphism
        
        animal1.Sleep(); // Calls Animal.Sleep() - compile-time polymorphism
        animal2.Sleep(); // Calls Animal.Sleep() - compile-time polymorphism
        
        Console.WriteLine("\n--- Direct Object Access ---");
        // When accessing directly, the hidden method is called
        dog.Move();  // Calls Dog.Move()
        cat.Move();  // Calls Cat.Move()
        
        dog.Sleep(); // Calls Dog.Sleep()
        cat.Sleep(); // Calls Cat.Sleep()
        
        Console.WriteLine("\n--- Casting to Access Hidden Methods ---");
        // To call the hidden method through base reference, cast to derived type
        ((Dog)animal1).Move();  // Calls Dog.Move()
        ((Cat)animal2).Move();  // Calls Cat.Move()
    }
}

When to Use Method Hiding:

  • When you want to provide a completely different implementation
  • When you don't want polymorphic behavior
  • When you need to break the inheritance chain for a specific method

When to Use Method Overriding:

  • When you want to extend or modify base class behavior
  • When you want polymorphic behavior
  • When you want to maintain the inheritance relationship

Best Practices:

  • Prefer override over new for better object-oriented design
  • Use new only when you intentionally want to hide a method
  • Always document when using method hiding
  • Consider if the base class method should be virtual instead