Polymorphism is one of the core concepts of Object-Oriented Programming (OOP) in C#. It allows objects to be treated as instances of their parent class rather than their actual class. The two main types of polymorphism in C# are compile-time (or static) polymorphism and runtime (or dynamic) polymorphism.
Key Concepts
-
Compile-time Polymorphism (Method Overloading)
- Achieved by method overloading and operator overloading.
- The method to be invoked is determined at compile time.
-
Runtime Polymorphism (Method Overriding)
- Achieved by method overriding using inheritance and interfaces.
- The method to be invoked is determined at runtime.
Compile-time Polymorphism
Method Overloading
Method overloading allows a class to have multiple methods with the same name but different parameters.
public class MathOperations { public int Add(int a, int b) { return a + b; } public double Add(double a, double b) { return a + b; } public int Add(int a, int b, int c) { return a + b + c; } }
Explanation
- The
Add
method is overloaded with different parameter lists. - The correct method is chosen based on the arguments passed during the method call.
Practical Example
class Program { static void Main(string[] args) { MathOperations math = new MathOperations(); Console.WriteLine(math.Add(2, 3)); // Output: 5 Console.WriteLine(math.Add(2.5, 3.5)); // Output: 6.0 Console.WriteLine(math.Add(1, 2, 3)); // Output: 6 } }
Runtime Polymorphism
Method Overriding
Method overriding allows a subclass to provide a specific implementation of a method that is already defined in its superclass.
public class Animal { public virtual void MakeSound() { Console.WriteLine("Animal makes a sound"); } } public class Dog : Animal { public override void MakeSound() { Console.WriteLine("Dog barks"); } } public class Cat : Animal { public override void MakeSound() { Console.WriteLine("Cat meows"); } }
Explanation
- The
MakeSound
method in theAnimal
class is marked asvirtual
, allowing it to be overridden in derived classes. - The
Dog
andCat
classes override theMakeSound
method to provide their specific implementations.
Practical Example
class Program { static void Main(string[] args) { Animal myDog = new Dog(); Animal myCat = new Cat(); myDog.MakeSound(); // Output: Dog barks myCat.MakeSound(); // Output: Cat meows } }
Exercises
Exercise 1: Method Overloading
Create a class Calculator
with overloaded methods Multiply
that can handle:
- Two integers
- Two doubles
- Three integers
Solution:
public class Calculator { public int Multiply(int a, int b) { return a * b; } public double Multiply(double a, double b) { return a * b; } public int Multiply(int a, int b, int c) { return a * b * c; } } class Program { static void Main(string[] args) { Calculator calc = new Calculator(); Console.WriteLine(calc.Multiply(2, 3)); // Output: 6 Console.WriteLine(calc.Multiply(2.5, 3.5)); // Output: 8.75 Console.WriteLine(calc.Multiply(1, 2, 3)); // Output: 6 } }
Exercise 2: Method Overriding
Create a base class Shape
with a method Draw
. Create derived classes Circle
and Rectangle
that override the Draw
method to print specific messages.
Solution:
public class Shape { public virtual void Draw() { Console.WriteLine("Drawing a shape"); } } public class Circle : Shape { public override void Draw() { Console.WriteLine("Drawing a circle"); } } public class Rectangle : Shape { public override void Draw() { Console.WriteLine("Drawing a rectangle"); } } class Program { static void Main(string[] args) { Shape myCircle = new Circle(); Shape myRectangle = new Rectangle(); myCircle.Draw(); // Output: Drawing a circle myRectangle.Draw(); // Output: Drawing a rectangle } }
Common Mistakes and Tips
- Not using
virtual
andoverride
keywords correctly: Ensure the base class method is marked withvirtual
and the derived class method withoverride
. - Confusing method overloading with method overriding: Overloading is about different parameter lists, while overriding is about redefining a method in a derived class.
- Using the wrong method signature: Ensure the method signatures are different for overloading and the same for overriding.
Conclusion
Polymorphism in C# allows for flexible and reusable code. By understanding and applying both compile-time and runtime polymorphism, you can create more dynamic and maintainable applications. In the next topic, we will delve into encapsulation, another fundamental OOP concept.
C# Programming Course
Module 1: Introduction to C#
- Introduction to C#
- Setting Up the Development Environment
- Hello World Program
- Basic Syntax and Structure
- Variables and Data Types
Module 2: Control Structures
Module 3: Object-Oriented Programming
- Classes and Objects
- Methods
- Constructors and Destructors
- Inheritance
- Polymorphism
- Encapsulation
- Abstraction
Module 4: Advanced C# Concepts
- Interfaces
- Delegates and Events
- Generics
- Collections
- LINQ (Language Integrated Query)
- Asynchronous Programming
Module 5: Working with Data
Module 6: Advanced Topics
- Reflection
- Attributes
- Dynamic Programming
- Memory Management and Garbage Collection
- Multithreading and Parallel Programming