Abstract classes vs Interfaces in .NET Core
Abstract classes vs Interfaces in .NET Core
1. Abstract Class
An abstract class serves as a base class that provides
shared functionality but cannot be instantiated directly. It can contain both concrete
(implemented) methods and abstract methods, which must be
implemented by subclasses. Abstract classes allow for default behavior while
ensuring that subclasses provide specific implementations for certain methods.
When to use an abstract class:
- Shared
functionality: For providing common functionality (methods,
properties, fields) that can be reused across multiple classes.
- Partial
implementation: For default code that can be shared but still requires
subclasses to implement specific details.
- Inheritance
hierarchies: For cases where a class represents a specific type of
another class, and subclassing is appropriate.
- Need
for fields or constructor logic: Abstract classes can have fields,
properties, and constructors, which interfaces cannot.
Example:
public abstract class Vehicle
{
public string
Model { get; set; }
public void
StartEngine()
{
Console.WriteLine("Engine started...");
}
// Abstract method
- subclasses must implement this
public abstract
void Drive();
}
public class Car : Vehicle
{
public override
void Drive()
{
Console.WriteLine("Driving the car...");
}
}
public class Truck : Vehicle
{
public override
void Drive()
{
Console.WriteLine("Driving the truck...");
}
}
2. Interface
An interface defines a contract, specifying the methods or
properties that a class must implement, but it does not provide any
implementation. All methods in an interface are abstract, and it cannot have
fields or provide state management. Interfaces are used to define behaviors
that classes must fulfill.
When to use an interface:
- No
shared implementation: For cases where only method signatures are
required, and implementation is left to the implementing classes.
- Multiple
inheritance: For situations where a class should implement multiple
behaviors from different interfaces, enabling flexibility.
- Loose
coupling: For designs where classes need to be decoupled and implement
various sets of behaviors.
Example:
public interface IPrintable
{
void Print();
}
public interface IScanable
{
void Scan();
}
public class Printer : IPrintable
{
public void
Print()
{
Console.WriteLine("Printing the document...");
}
}
public class Scanner : IScanable
{
public void Scan()
{
Console.WriteLine("Scanning
the document...");
}
}
public class AllInOnePrinter : IPrintable, IScanable
{
public void
Print()
{
Console.WriteLine("Printing the document...");
}
public void Scan()
{
Console.WriteLine("Scanning the document...");
}
}
Key Differences
Feature |
Abstract Class |
Interface |
Implementation |
Can provide both implemented and abstract methods. |
Can only provide method signatures (no implementation). |
State |
Can contain fields, properties, and constructors. |
Cannot contain fields or state (only method signatures). |
Multiple Inheritance |
A class can only inherit one abstract class. |
A class can implement multiple interfaces. |
Purpose |
To provide shared functionality with possible abstraction. |
To define a contract that classes must implement. |
Use Case |
When classes share behavior, or some default
implementation is needed. |
When enforcing that unrelated classes adhere to the same
contract. |
When to Choose One Over the Other:
- Choose
an abstract class if:
- Shared
behavior is needed, and subclasses need to inherit both functionality and
abstract methods.
- A
clear "is-a" relationship exists between the base class and the
derived classes.
- There
is a need for fields or constructor logic that can be shared across
classes.
- Choose
an interface if:
- The
focus is on defining a contract that various classes can implement.
- Multiple,
unrelated classes need to implement the same set of methods.
- Flexibility
is desired, and classes should not be restricted to a single inheritance
chain.
In conclusion, abstract classes are suitable when shared functionality is needed, while interfaces are best when a contract must be defined that unrelated classes can implement. Both play important roles in object-oriented design, supporting code reusability, flexibility, and maintainability.
Comments
Post a Comment