
1. What is Dynamic Polymorphism?
Dynamic polymorphism is a concept in object-oriented programming where the method to be executed is determined at runtime rather than compile time. In C#, this is achieved using interfaces or abstract classes. With interfaces, you can define a contract, and different classes can implement that contract in their own way. At runtime, the appropriate method is called based on the actual object type.
2. Layman’s Explanation with Real-Life Example
Think of a remote control for electronic devices:
- The remote control has buttons like
PowerOn()
andPowerOff()
. - Different devices (e.g., TV, AC, Fan) can be controlled by the same remote, but each device responds differently to the same buttons.
Here, the remote control is like an interface, and the devices are like classes that implement the interface. The behavior of the buttons depends on the device you’re controlling (dynamic polymorphism).
3. Complete Solution: Real-World Project Example
Let’s build a smart home system where different devices (e.g., Light, Fan, AC) can be controlled using a universal remote. We’ll use dynamic polymorphism with interfaces to achieve this.
Step 1: Define the Interface
We’ll create an IDevice
interface that defines common methods for all devices.
public interface IDevice { void TurnOn(); void TurnOff(); void Adjust(int level); }
Step 2: Implement the Interface in Different Classes
We’ll create three classes (Light
, Fan
, AC
) that implement the IDevice
interface.
public class Light : IDevice { public void TurnOn() { Console.WriteLine("Light is turned on."); } public void TurnOff() { Console.WriteLine("Light is turned off."); } public void Adjust(int level) { Console.WriteLine($"Light brightness adjusted to {level}%."); } } public class Fan : IDevice { public void TurnOn() { Console.WriteLine("Fan is turned on."); } public void TurnOff() { Console.WriteLine("Fan is turned off."); } public void Adjust(int level) { Console.WriteLine($"Fan speed adjusted to level {level}."); } } public class AC : IDevice { public void TurnOn() { Console.WriteLine("AC is turned on."); } public void TurnOff() { Console.WriteLine("AC is turned off."); } public void Adjust(int level) { Console.WriteLine($"AC temperature set to {level}°C."); } }
Step 3: Create a Universal Remote Control
The remote control will work with any device that implements the IDevice
interface.
public class RemoteControl { private IDevice _device; public RemoteControl(IDevice device) { _device = device; } public void TurnOnDevice() { _device.TurnOn(); } public void TurnOffDevice() { _device.TurnOff(); } public void AdjustDevice(int level) { _device.Adjust(level); } }
Step 4: Use the Remote Control in a Program
Let’s create a program to demonstrate dynamic polymorphism.
class Program { static void Main(string[] args) { // Create devices IDevice light = new Light(); IDevice fan = new Fan(); IDevice ac = new AC(); // Create remote controls for each device RemoteControl lightRemote = new RemoteControl(light); RemoteControl fanRemote = new RemoteControl(fan); RemoteControl acRemote = new RemoteControl(ac); // Control the devices using the remote lightRemote.TurnOnDevice(); lightRemote.AdjustDevice(75); lightRemote.TurnOffDevice(); fanRemote.TurnOnDevice(); fanRemote.AdjustDevice(3); fanRemote.TurnOffDevice(); acRemote.TurnOnDevice(); acRemote.AdjustDevice(22); acRemote.TurnOffDevice(); } }
Step 5: Output
When you run the program, you’ll see the following output:
Light is turned on. Light brightness adjusted to 75%. Light is turned off. Fan is turned on. Fan speed adjusted to level 3. Fan is turned off. AC is turned on. AC temperature set to 22°C. AC is turned off.
Step 6: Explanation
- Dynamic Polymorphism:
- The
RemoteControl
class works with any object that implements theIDevice
interface. - At runtime, the appropriate
TurnOn()
,TurnOff()
, andAdjust()
methods are called based on the actual object type (e.g.,Light
,Fan
,AC
). - Flexibility:
- You can add new devices (e.g.,
Heater
,Speaker
) without modifying theRemoteControl
class.
Step 7: Best Practices and Features
- Best Practices:
- Use interfaces to define clear contracts for behavior.
- Keep interfaces small and focused (Single Responsibility Principle).
- Favor composition over inheritance for flexibility.
- Use meaningful names for interfaces and methods.
- Document the purpose of each interface and method.
- Features:
- Enables runtime flexibility and extensibility.
- Promotes loose coupling between components.
- Allows you to write generic code that works with multiple implementations.
Step 8: Pros and Cons
- Pros:
- Flexibility: You can add new implementations without modifying existing code.
- Reusability: The
RemoteControl
class works with anyIDevice
. - Maintainability: Changes to one class don’t affect others.
- Cons:
- Slightly more complex than static polymorphism.
- Requires careful design to avoid overly complex hierarchies.
Step 9: Alternatives
- Abstract Classes: Use abstract classes if you need to provide default implementations for some methods.
- Delegates/Events: Use delegates or events for callback-based behavior.
Step 10: When to Use Dynamic Polymorphism with Interfaces
- Use dynamic polymorphism when:
- You need runtime flexibility (e.g., plugins, extensible systems).
- You want to decouple your code and promote reusability.
- You have multiple classes that share common behavior but implement it differently.
Step 11: Complete Solution Code
Here’s the complete code for the solution:
using System; // Interface public interface IDevice { void TurnOn(); void TurnOff(); void Adjust(int level); } // Light class public class Light : IDevice { public void TurnOn() { Console.WriteLine("Light is turned on."); } public void TurnOff() { Console.WriteLine("Light is turned off."); } public void Adjust(int level) { Console.WriteLine($"Light brightness adjusted to {level}%."); } } // Fan class public class Fan : IDevice { public void TurnOn() { Console.WriteLine("Fan is turned on."); } public void TurnOff() { Console.WriteLine("Fan is turned off."); } public void Adjust(int level) { Console.WriteLine($"Fan speed adjusted to level {level}."); } } // AC class public class AC : IDevice { public void TurnOn() { Console.WriteLine("AC is turned on."); } public void TurnOff() { Console.WriteLine("AC is turned off."); } public void Adjust(int level) { Console.WriteLine($"AC temperature set to {level}°C."); } } // RemoteControl class public class RemoteControl { private IDevice _device; public RemoteControl(IDevice device) { _device = device; } public void TurnOnDevice() { _device.TurnOn(); } public void TurnOffDevice() { _device.TurnOff(); } public void AdjustDevice(int level) { _device.Adjust(level); } } // Program class Program { static void Main(string[] args) { // Create devices IDevice light = new Light(); IDevice fan = new Fan(); IDevice ac = new AC(); // Create remote controls for each device RemoteControl lightRemote = new RemoteControl(light); RemoteControl fanRemote = new RemoteControl(fan); RemoteControl acRemote = new RemoteControl(ac); // Control the devices using the remote lightRemote.TurnOnDevice(); lightRemote.AdjustDevice(75); lightRemote.TurnOffDevice(); fanRemote.TurnOnDevice(); fanRemote.AdjustDevice(3); fanRemote.TurnOffDevice(); acRemote.TurnOnDevice(); acRemote.AdjustDevice(22); acRemote.TurnOffDevice(); } }