C# > Object-Oriented Programming (OOP) > Polymorphism > Abstract Classes and Methods
Abstract Class and Polymorphic Methods Example
This example demonstrates abstract classes and polymorphic methods in C#. Abstract classes cannot be instantiated directly and often contain abstract methods, which must be implemented by derived classes. Polymorphism allows objects of different classes to be treated as objects of a common type.
Code Example
This code demonstrates abstract classes, abstract methods, and polymorphism. The `Shape` class is an abstract class with an abstract method `CalculateArea()`. The `Circle` and `Rectangle` classes inherit from `Shape` and provide concrete implementations for `CalculateArea()`. The virtual method `GetShapeType()` is overridden as well in each derived class. The `Main` method creates instances of `Circle` and `Rectangle` and treats them as `Shape` objects, showcasing polymorphism.
using System;
// Abstract Class
abstract class Shape
{
// Abstract method (no implementation in the base class)
public abstract double CalculateArea();
// Virtual method (can be overridden in derived classes)
public virtual string GetShapeType()
{
return "Shape";
}
// Concrete method (shared by all derived classes)
public void Display()
{
Console.WriteLine("Shape Type: " + GetShapeType() + ", Area: " + CalculateArea());
}
}
// Derived Class 1
class Circle : Shape
{
public double Radius { get; set; }
public Circle(double radius)
{
Radius = radius;
}
// Implementing the abstract method
public override double CalculateArea()
{
return Math.PI * Radius * Radius;
}
public override string GetShapeType()
{
return "Circle";
}
}
// Derived Class 2
class Rectangle : Shape
{
public double Width { get; set; }
public double Height { get; set; }
public Rectangle(double width, double height)
{
Width = width;
Height = height;
}
// Implementing the abstract method
public override double CalculateArea()
{
return Width * Height;
}
public override string GetShapeType()
{
return "Rectangle";
}
}
public class Example
{
public static void Main(string[] args)
{
// Cannot instantiate an abstract class directly
// Shape shape = new Shape(); // This will cause a compile-time error
// Polymorphism in action
Shape circle = new Circle(5);
Shape rectangle = new Rectangle(4, 6);
circle.Display(); // Output: Shape Type: Circle, Area: 78.53981633974483
rectangle.Display(); // Output: Shape Type: Rectangle, Area: 24
}
}
Concepts Behind the Snippet
This example illustrates the core concepts of object-oriented programming: Abstraction and Polymorphism.
Abstraction: The `Shape` class abstracts the common characteristics of geometric shapes without providing concrete implementations for all methods. It hides complexity by defining a general interface.
Polymorphism: The ability to treat objects of different types (e.g., `Circle` and `Rectangle`) as objects of a common type (`Shape`). This is achieved through inheritance and the use of abstract/virtual methods.
Real-Life Use Case
Consider a system for processing different types of documents. You could have an abstract `Document` class with derived classes like `PDFDocument`, `WordDocument`, and `TextDocument`. Each derived class would implement a `Print()` method specific to its format. The system could then process a collection of `Document` objects polymorphically, calling the appropriate `Print()` method for each document type without needing to know its specific type in advance.
Best Practices
Interview Tip
Be prepared to explain the difference between abstract classes and interfaces. Abstract classes can have both abstract and concrete members, while interfaces can only have abstract members (until C# 8.0, when default interface implementations were introduced). Also, a class can inherit from multiple interfaces, but only one abstract class.
When to Use Them
Use abstract classes when you have a clear inheritance hierarchy and want to share some common implementation details among derived classes. Use interfaces when you want to define a contract that multiple unrelated classes can implement.
Memory Footprint
Abstract classes themselves don't directly contribute to the memory footprint because you can't instantiate them. However, the classes that inherit from them will have the memory footprint based on the properties and variables declared in the base class and its own class properties and variables. The memory impact is almost the same as a standard inheritance.
Alternatives
Pros
Cons
FAQ
-
Can an abstract class have a constructor?
Yes, an abstract class can have a constructor. While you can't instantiate an abstract class directly, the constructor is used when a derived class is instantiated. The derived class constructor calls the abstract class constructor as part of its initialization process. -
Can an abstract method be private?
No, an abstract method cannot be private. Abstract methods are intended to be implemented by derived classes, so they must be accessible to those classes. Therefore, they must be declared as `public` or `protected`. -
What happens if a derived class doesn't implement all abstract methods?
If a derived class doesn't implement all abstract methods from its abstract base class, the derived class must also be declared as abstract. This means that it cannot be instantiated either, and it must be further derived from by another class that provides concrete implementations for all abstract methods.