C# > Object-Oriented Programming (OOP) > Polymorphism > Abstract Classes and Methods
Polymorphism with Interfaces and Abstract Classes
This example demonstrates polymorphism using both interfaces and abstract classes in C#. It shows how different classes can implement the same interface or inherit from the same abstract class and exhibit different behaviors.
Code Example
This code demonstrates polymorphism using both an interface (`ISpeakable`) and an abstract class (`Animal`). The `Animal` class implements the `ISpeakable` interface and declares an abstract method `Speak()`. The `Dog` and `Cat` classes inherit from `Animal` and provide concrete implementations for `Speak()`. The `Translator` class implement the ISpeakable interface directly. The `Main` method shows how to treat objects of different classes as objects of a common interface or abstract class type.
using System;
// Interface defining a common behavior
public interface ISpeakable
{
string Speak();
}
// Abstract class implementing the interface
public abstract class Animal : ISpeakable
{
public string Name { get; set; }
public Animal(string name)
{
Name = name;
}
// Abstract method to be implemented by derived classes
public abstract string Speak();
// Virtual method
public virtual string Describe()
{
return $"This is a {GetType().Name} named {Name}.";
}
}
// Concrete class inheriting from Animal
public class Dog : Animal
{
public Dog(string name) : base(name) { }
public override string Speak()
{
return "Woof!";
}
public override string Describe()
{
return base.Describe() + " It's a good boy!";
}
}
// Concrete class inheriting from Animal
public class Cat : Animal
{
public Cat(string name) : base(name) { }
public override string Speak()
{
return "Meow!";
}
}
// Concrete class implementing the interface directly
public class Translator : ISpeakable
{
private string message;
public Translator(string message)
{
this.message = message;
}
public string Speak()
{
return $"Translated: {message}";
}
}
public class Example
{
public static void Main(string[] args)
{
// Polymorphism with interface
ISpeakable dog = new Dog("Buddy");
ISpeakable cat = new Cat("Whiskers");
ISpeakable translator = new Translator("Hello");
Console.WriteLine(dog.Speak()); // Output: Woof!
Console.WriteLine(cat.Speak()); // Output: Meow!
Console.WriteLine(translator.Speak()); // Output: Translated: Hello
// Polymorphism with abstract class
Animal animalDog = new Dog("Rover");
Animal animalCat = new Cat("Mittens");
Console.WriteLine(animalDog.Describe()); // Output: This is a Dog named Rover. It's a good boy!
Console.WriteLine(animalCat.Describe()); // Output: This is a Cat named Mittens.
}
}
Concepts Behind the Snippet
Real-Life Use Case
Consider a game development scenario where you have different types of game entities (e.g., characters, enemies, items). You can define an interface like `IInteractable` with a method `Interact()`. Each game entity can implement this interface and provide its own specific interaction logic. The game engine can then polymorphically interact with any `IInteractable` object without knowing its specific type.
Best Practices
Interview Tip
Be prepared to discuss the trade-offs between interfaces and abstract classes. Interfaces provide greater flexibility in terms of multiple inheritance, while abstract classes allow you to share implementation details and enforce a specific structure on derived classes.
When to use them
Use interfaces to define a capability, or behavior, that different classes can implement. This allows you to treat these different classes in a uniform way, using polymorphism. Use abstract classes to provide a common base for a group of related classes, allowing you to share code and enforce a certain structure. Abstract classes are useful when you have some default behavior that you want to provide, but you also want to ensure that subclasses implement certain methods in their own way.
Memory footprint
Interfaces and abstract classes have different impacts on memory. Interfaces, being a contract, don't add any data or implementation directly to classes that implement them. Abstract classes, on the other hand, can include data members and method implementations, which contribute to the memory footprint of any class that inherits from them.
Alternatives
Pros
Cons
FAQ
-
Can an interface inherit from another interface?
Yes, an interface can inherit from one or more other interfaces. This allows you to create more complex interfaces that combine the capabilities of multiple interfaces. -
Can an abstract class implement an interface?
Yes, an abstract class can implement one or more interfaces. This is a common pattern for providing a default implementation for some of the interface methods while leaving others to be implemented by derived classes. -
Is it possible to create a sealed class that implements an interface?
Yes, a sealed class can implement an interface. A sealed class cannot be inherited from, so it must provide a complete implementation for all members of the interface. This can be useful when you want to create a final, non-extensible implementation of a particular interface.