
The virtual and override keywords in C# are used to enable runtime polymorphism (also known as method overriding). They allow a derived class to provide a specific implementation of a method that is already defined in its base class. This is a key feature of Object-Oriented Programming (OOP) that promotes flexibility and extensibility.
1. What Are virtual and override Keywords?
virtual Keyword
- What it is: The
virtualkeyword is used in a base class to mark a method, property, or indexer as overridable. This means derived classes can provide their own implementation. - Example in Real Life: Think of a generic recipe for making a sandwich. The base recipe (virtual method) can be customized (overridden) to make a specific type of sandwich (e.g., veggie, chicken).
override Keyword
- What it is: The
overridekeyword is used in a derived class to provide a new implementation of a method, property, or indexer that is marked asvirtualin the base class. - Example in Real Life: Customizing the generic sandwich recipe to make a chicken sandwich. You override the base recipe to add chicken instead of generic ingredients.
2. How Do They Work?
Base Class with virtual Method
class Sandwich
{
public virtual void Make()
{
Console.WriteLine("Making a generic sandwich.");
}
}
Derived Class with override Method
class ChickenSandwich : Sandwich
{
public override void Make()
{
Console.WriteLine("Making a chicken sandwich.");
}
}
Usage
Sandwich mySandwich = new Sandwich(); mySandwich.Make(); // Output: Making a generic sandwich. mySandwich = new ChickenSandwich(); mySandwich.Make(); // Output: Making a chicken sandwich.
3. Real-Life Example
Imagine a vehicle manufacturing system:
- The base class
Vehiclehas avirtualmethodStartEngine(). - Derived classes like
CarandBikeoverride theStartEngine()method to provide their own implementation.
class Vehicle
{
public virtual void StartEngine()
{
Console.WriteLine("Engine started.");
}
}
class Car : Vehicle
{
public override void StartEngine()
{
Console.WriteLine("Car engine started with a key.");
}
}
class Bike : Vehicle
{
public override void StartEngine()
{
Console.WriteLine("Bike engine started with a kick.");
}
}
Vehicle vehicle = new Car();
vehicle.StartEngine(); // Output: Car engine started with a key.
vehicle = new Bike();
vehicle.StartEngine(); // Output: Bike engine started with a kick.
4. Best Practices and Features
Best Practices
- Use
virtualSparingly: Only mark methods asvirtualif you expect them to be overridden. - Follow Naming Conventions: Use meaningful names for methods to make it clear what they do.
- Avoid Overriding Non-Virtual Methods: Use
newkeyword instead if you must hide a non-virtual method (though this is generally discouraged). - Document Overridden Methods: Clearly document the behavior of overridden methods in derived classes.
- Respect the Liskov Substitution Principle: Ensure that overridden methods in derived classes don’t break the behavior expected by the base class.
Features
- Runtime Polymorphism: Enables dynamic method binding at runtime.
- Extensibility: Allows derived classes to extend or modify base class behavior.
- Code Reusability: Promotes reuse of base class logic while allowing customization.
5. Pros and Cons
Pros
- Flexibility: Derived classes can customize behavior without modifying the base class.
- Extensibility: New functionality can be added easily by creating new derived classes.
- Code Reusability: Common behavior can be defined in the base class and reused in derived classes.
Cons
- Complexity: Overuse of
virtualandoverridecan make the code harder to understand. - Performance Overhead: Runtime polymorphism introduces a slight performance overhead compared to compile-time binding.
- Tight Coupling: Overriding methods can create tight coupling between base and derived classes if not designed carefully.
6. Alternatives
Abstract Methods
- Use
abstractmethods in an abstract base class if you want to enforce that derived classes provide an implementation. - Example:
abstract class Vehicle
{
public abstract void StartEngine();
}
class Car : Vehicle
{
public override void StartEngine()
{
Console.WriteLine("Car engine started.");
}
}
Interfaces
- Use interfaces to define a contract that multiple classes can implement.
- Example:
interface IEngine
{
void Start();
}
class Car : IEngine
{
public void Start()
{
Console.WriteLine("Car engine started.");
}
}
Delegates
- Use delegates to pass methods as parameters, enabling dynamic behavior.
- Example:
delegate void StartEngineDelegate();
class Vehicle
{
public StartEngineDelegate StartEngine;
}
Vehicle car = new Vehicle();
car.StartEngine = () => Console.WriteLine("Car engine started.");
car.StartEngine();
7. When to Use virtual and override
- When You Need Custom Behavior: Use
virtualandoverridewhen derived classes need to provide their own implementation of a method. - When You Expect Future Extensions: Use
virtualif you anticipate that derived classes will need to modify or extend the behavior of the base class. - When You Want Runtime Polymorphism: Use
virtualandoverrideto enable dynamic method binding at runtime.
8. 10 Quality Keywords for Your Blog
"virtual and override in C#, method overriding in C#, runtime polymorphism, C# OOP concepts, virtual methods, override keyword, abstract methods in C#, C# best practices, Liskov substitution principle, C# inheritance"
Advanced Code Example
using System;
// Base class with virtual method
class Animal
{
public virtual void Speak()
{
Console.WriteLine("The animal makes a sound.");
}
}
// Derived classes overriding the virtual method
class Dog : Animal
{
public override void Speak()
{
Console.WriteLine("The dog barks.");
}
}
class Cat : Animal
{
public override void Speak()
{
Console.WriteLine("The cat meows.");
}
}
// Using polymorphism
class Program
{
static void Main()
{
Animal myAnimal = new Animal();
myAnimal.Speak(); // Output: The animal makes a sound.
myAnimal = new Dog();
myAnimal.Speak(); // Output: The dog barks.
myAnimal = new Cat();
myAnimal.Speak(); // Output: The cat meows.
}
}
Explanation of Advanced Code
- Base Class:
Animaldefines avirtualmethodSpeak(). - Derived Classes:
DogandCatoverride theSpeak()method to provide their own implementation. - Polymorphism: The
Speak()method behaves differently depending on the type of object at runtime.
By understanding and using virtual and override effectively, you can create flexible and extensible applications that adhere to OOP principles. These keywords are essential for implementing runtime polymorphism in C#.


