An abstract class is a class that exists only to be derived from. It cannot be instantiated, and it can declare abstract members: methods and properties with no body that every concrete derived class must implement. Everything else about it is an ordinary class: it can have fields, constructors and fully implemented methods that derived classes inherit.
Declaring an abstract class
Mark the class abstract, and mark each member that derived classes must supply abstract, ending it with a semicolon instead of a body:
Output:
Circle: area 7.07, perimeter 9.42
Rectangle: area 10.00, perimeter 13.00
Describe is written once, in the base class, and calls Area and Perimeter, which do not exist in Shape at all. That is the point of an abstract member: the base class can rely on it, and the compiler guarantees every concrete shape provides it. A derived class that forgets one does not compile:
class Triangle : Shape
{
public Triangle() : base("Triangle") { }
public override double Area() => 6;
}
// error CS0534: 'Triangle' does not implement inherited abstract member 'Shape.Perimeter()'
The fix is to implement Perimeter, or to mark Triangle itself abstract if it is an intermediate base for further classes.
Rules for abstract members
- An abstract member has no body and is implicitly virtual: derived classes implement it with
override. - Only abstract classes may contain abstract members. Putting one in a normal class is a compile error.
- Abstract members cannot be
private(nobody could override them) orstaticin a class. - Methods, properties, indexers and events can be abstract. Fields and constructors cannot.
- An abstract class does not have to contain any abstract member. Marking a class
abstractalone just prevents instantiation, useful for a base class that only makes sense through its subclasses.
An abstract property declares which accessors the derived class must provide:
abstract class Plan
{
public abstract decimal MonthlyPrice { get; }
public abstract string Name { get; }
}
class ProPlan : Plan
{
public override decimal MonthlyPrice => 12.99m;
public override string Name => "Pro";
}
Constructors in abstract classes
An abstract class can have constructors. They cannot be called with new, but every derived constructor runs one through : base(...), so they are where shared state is initialized and validated. Declare them protected, which says exactly that: only derived classes can use this.
The template method pattern
The most common reason to write an abstract class is to fix the order of an algorithm in the base class and let derived classes fill in individual steps. The base method that runs the steps is not virtual, so no subclass can reorder or skip them.
Output:
item,qty,price
Coffee beans,2,11.50
Filter papers,1,3.20
| Item | Qty | Price |
| --- | --- | --- |
| Coffee beans | 2 | 11.50 |
| Filter papers | 1 | 3.20 |
Total: 26.20
Each row is a named tuple, and the output is built with a StringBuilder. Note the mix: Header and Row are abstract because every format must decide them, and Footer is virtual with an empty default because most formats need nothing there. The steps are protected, so outside code can only call Export. Framework classes use the same idea: Stream and TextWriter are abstract base classes whose many convenience methods are built on a few members a derived class supplies (Read and Write for a stream, Write(char) for a text writer).
Abstract class vs interface
Both let you write code against a type without knowing the concrete class. They differ in what they can contain and how many a class can have:
| Abstract class | Interface | |
|---|---|---|
| A class can inherit or implement | one | many |
| Instance fields (state) | yes | no |
| Constructors | yes | no |
| Methods with a body | yes | yes, since C# 8 (default interface methods) |
| Static members | yes | yes, since C# 8; static abstract members since C# 11 |
| Access modifiers on members | any | public by default; others allowed since C# 8 |
| Structs can use it | no | yes |
| Adding a member later | safe if it is not abstract | breaks implementers, unless it has a default body |
Default interface methods (C# 8) narrowed the gap, but not the core difference:
public interface ILogger
{
void Write(string message);
void Error(string message) => Write("ERROR: " + message); // default implementation: C# 8, .NET Core 3.0+
}
A default method still cannot touch instance fields, because the interface has none; it can only call other members of the interface.
A practical way to choose:
- Interface when you describe a capability that unrelated types can have (
IComparable<T>,IDisposable,IShippingProvider), when structs should be able to take part, or when a class needs several such roles. Most dependency injection code is written against interfaces for this reason. - Abstract class when the derived types are genuinely variations of one thing and share state or a fixed algorithm, like the exporters above.
- Both is common: an interface for callers to depend on, and an abstract base class that implements it and saves implementers from rewriting the shared parts. The interfaces page covers the interface side in detail.
Common mistakes
- Trying to instantiate the base class.
new Shape(...)is CS0144. Instantiate a derived class. - Forgetting
overrideon the implementation. Writingpublic double Area()in the derived class does not implement the abstract member; the compiler reports CS0534 for the missing implementation, plus a warning that the new method hides the inherited one. - A public constructor on an abstract class. Harmless but misleading. Use
protected. - Abstract classes with no shared code. If the base class has only abstract members and no state, an interface says the same thing and does not use up the single base class slot.
- Calling abstract members from the base constructor. The derived implementation runs before the derived constructor's body, so fields that body assigns are still
0ornull.
Frequently Asked Questions
What is an abstract class in C#?
A class marked abstract is meant only as a base class: you cannot create an instance of it with new (error CS0144). It can contain normal fields, constructors and methods, plus abstract members that have no body and must be implemented by every non-abstract derived class.
What is the difference between an abstract class and an interface in C#?
A class can derive from only one abstract class but implement many interfaces. An abstract class can hold state (instance fields), constructors and members of any access level, and is the natural place for shared implementation. An interface describes a capability with no instance state; since C# 8 it may include default method bodies, but it still cannot have instance fields or constructors.
What is the difference between abstract and virtual methods in C#?
A virtual method has a body that derived classes may override. An abstract method has no body and derived classes must override it, otherwise they are abstract themselves (error CS0534 for a concrete class). Abstract methods can only appear in abstract classes.
Can an abstract class have a constructor in C#?
Yes. It runs when a derived class is constructed, through : base(...), and typically initializes the shared fields. Declare it protected: a public constructor on an abstract class suggests callers can use it, and they cannot.
Why can't I create an instance of an abstract class?
Because it may have abstract members with no implementation: calling new Shape().Area() would have no code to run. The compiler reports CS0144 ("Cannot create an instance of the abstract type or interface"). Create an instance of a concrete derived class instead, and hold it in a variable of the abstract type if you like: Shape s = new Circle(2);.