What is the difference between virtual, override, and new keywords in C#?
12 minintermediateOOPinheritancepolymorphismkeywords
Quick Answer
virtual allows a method to be overridden in derived classes. override provides a new implementation of a virtual/abstract method. new hides a base class member with a new implementation (method hiding). Virtual/override enables polymorphism, while new breaks the inheritance chain and creates separate methods.
Detailed Answer
These three keywords control how methods behave in inheritance hierarchies and are fundamental to understanding polymorphism in C#.
1. virtual Keyword:
- Marks a method in the base class as overridable
- Allows derived classes to provide their own implementation
- Enables runtime polymorphism
2. override Keyword:
- Used in derived classes to replace the virtual method implementation
- Provides runtime polymorphism - the correct method is called based on the actual object type
- Must override a virtual, abstract, or override method
3. new Keyword:
- Used for method hiding (not overriding)
- Creates a new method that hides the base class method
- Provides compile-time polymorphism - method called depends on reference type, not object type
Example:
public class Animal
{
// Virtual method - can be overridden
public virtual void MakeSound()
{
Console.WriteLine("Animal makes a sound");
}
// Regular method - can be hidden with 'new'
public void Move()
{
Console.WriteLine("Animal moves");
}
}
public class Dog : Animal
{
// Override - runtime polymorphism
public override void MakeSound()
{
Console.WriteLine("Dog barks: Woof!");
}
// Method hiding with 'new' - compile-time polymorphism
public new void Move()
{
Console.WriteLine("Dog runs on four legs");
}
}
public class Cat : Animal
{
// Override - runtime polymorphism
public override void MakeSound()
{
Console.WriteLine("Cat meows: Meow!");
}
// Method hiding with 'new' - compile-time polymorphism
public new void Move()
{
Console.WriteLine("Cat walks gracefully");
}
}
// Demonstration of the differences
public class PolymorphismDemo
{
public static void DemonstratePolymorphism()
{
// Runtime Polymorphism (override)
Animal animal1 = new Dog();
Animal animal2 = new Cat();
// Calls the overridden method based on actual object type
animal1.MakeSound(); // Output: "Dog barks: Woof!"
animal2.MakeSound(); // Output: "Cat meows: Meow!"
// Compile-time Polymorphism (new)
// Calls the method based on reference type, not object type
animal1.Move(); // Output: "Animal moves" (base class method)
animal2.Move(); // Output: "Animal moves" (base class method)
// To call the hidden method, need to cast to derived type
((Dog)animal1).Move(); // Output: "Dog runs on four legs"
((Cat)animal2).Move(); // Output: "Cat walks gracefully"
// Direct instantiation calls the correct method
Dog dog = new Dog();
Cat cat = new Cat();
dog.MakeSound(); // Output: "Dog barks: Woof!"
dog.Move(); // Output: "Dog runs on four legs"
cat.MakeSound(); // Output: "Cat meows: Meow!"
cat.Move(); // Output: "Cat walks gracefully"
}
}
Key Differences Summary:
| Aspect | virtual | override | new |
|---|---|---|---|
| Purpose | Makes method overridable | Replaces virtual method | Hides base method |
| Polymorphism | Enables runtime | Runtime polymorphism | Compile-time binding |
| Method Resolution | Based on object type | Based on object type | Based on reference type |
| Base Method Call | Can call with base. | Can call with base. | Cannot call base method |
| When to Use | Base class design | Derived class implementation | Method hiding scenarios |
Best Practices:
- Use
virtualin base classes when you want derived classes to customize behavior - Use
overridewhen you want true polymorphism and method replacement - Use
newsparingly - only when you need to hide a method and don't want polymorphism - Prefer
overrideovernewfor better object-oriented design - Always call
base.MethodName()in overrides when you want to extend, not replace, functionality