Read the syntax
An abstract class cannot be instantiated directly. It may contain shared implemented members and abstract members that concrete subclasses must override.
A base-class reference can still hold a concrete derived object. Calling its overridden member uses the derived implementation while shared base methods remain available.
Syntax
abstract class ClassName {\n public abstract returnType MethodName();\n}Examples
Basic Abstract Class
Defining a base class that mixes concrete and abstract methods.
// Animal a = new Animal("Generic"); // Error - can't instantiate abstract class
Dog dog = new Dog("Rex");
dog.MakeSound();
dog.Sleep();
public abstract class Animal
{
protected string Name;
protected Animal(string name)
{
Name = name;
}
public abstract void MakeSound(); // no body - subclasses must implement
public void Sleep() // concrete method, shared by all subclasses
{
Console.WriteLine($"{Name} is sleeping");
}
}
public class Dog : Animal
{
public Dog(string name) : base(name) { }
public override void MakeSound() => Console.WriteLine($"{Name} says: Woof!");
}- Defining a base class that mixes concrete and abstract methods.
- An abstract class cannot be instantiated directly. It may contain shared implemented members and abstract members that concrete subclasses must override.
- Dog supplies MakeSound while inheriting Sleep. Constructing Dog prints Rex’s sound and sleeping messages; the commented Animal construction would not compile.
Enforcing a Common Structure
Multiple subclasses implementing the same abstract method differently.
Employee m = new Manager("John", 60000);
Console.WriteLine(m.TotalPay()); // 72000
public abstract class Employee
{
protected string Name;
protected double BaseSalary;
protected Employee(string name, double baseSalary)
{
Name = name;
BaseSalary = baseSalary;
}
public abstract double CalculateBonus();
public double TotalPay() => BaseSalary + CalculateBonus();
}
public class Manager : Employee
{
public Manager(string name, double baseSalary) : base(name, baseSalary) { }
public override double CalculateBonus() => BaseSalary * 0.2;
}
public class Developer : Employee
{
public Developer(string name, double baseSalary) : base(name, baseSalary) { }
public override double CalculateBonus() => BaseSalary * 0.1;
}- Multiple subclasses implementing the same abstract method differently.
- An abstract class cannot be instantiated directly. It may contain shared implemented members and abstract members that concrete subclasses must override.
- Manager calculates a 20 percent bonus from its base salary. TotalPay calls that override through an Employee reference and prints 72000.
Best practices
- Use an abstract class when subclasses share both state (fields) and some common implemented behavior, not just a method signature
- Use an interface instead when unrelated classes just need to share a capability, with no shared fields or implementation
- A class can only extend one abstract class but can implement multiple interfaces - factor that into your design choice
- Make a method abstract only when every subclass genuinely needs its own distinct implementation - otherwise provide a sensible default in the abstract class
Runtime & versions
.NET runtime. Feature availability depends on the language and runtime version used by your project; consult the official reference below.
C# language reference