Абстрактные и запечатанные классы и члены классов (Руководство по программированию на C#)

Ключевое слово abstract позволяет создавать классы и члены классов, которые являются неполными и должны быть реализованы в производном классе.

Ключевое слово sealed позволяет предотвратить наследование класса или определенных членов класса, помеченных ранее как virtual.

Абстрактные классы и члены классов

Классы могут быть объявлены абстрактными путем помещения ключевого слова abstract перед определением класса. Например:

public abstract class A
{
    // Class members here.
}

Создавать экземпляры абстрактного класса нельзя. Назначение абстрактного класса заключается в предоставлении общего определения для базового класса, которое могут совместно использовать несколько производных классов. Например, в библиотеке классов может быть определен абстрактный класс, используемый в качестве параметра для многих из ее функций, поэтому программисты, использующие эту библиотеку, должны задать свою реализацию этого класса, создав производный класс.

Абстрактные классы могут определять абстрактные методы. Для этого перед типом возвращаемого значения метода необходимо поместить ключевое слово abstract. Например:

public abstract class A
{
    public abstract void DoWork(int i);
}

Абстрактные методы не имеют реализации, поэтому определение такого метода заканчивается точкой с запятой вместо обычного блока метода. Классы, производные от абстрактного класса, должны реализовывать все абстрактные методы. Если абстрактный класс наследует виртуальный метод из базового класса, абстрактный класс может переопределить виртуальный метод с помощью абстрактного метода. Например:

// compile with: -target:library
public class D
{
    public virtual void DoWork(int i)
    {
        // Original implementation.
    }
}

public abstract class E : D
{
    public abstract override void DoWork(int i);
}

public class F : E
{
    public override void DoWork(int i)
    {
        // New implementation.
    }
}

Если метод virtual объявляется как abstract, он все равно считается виртуальным по отношению к любому классу, наследующему от абстрактного класса. Класс, наследующий абстрактный метод, не может получать доступ к исходной реализации метода (так, в предыдущем примере DoWork для класса F не может вызывать DoWork для класса D). Таким образом, абстрактный класс может принудительно задавать необходимость предоставлять новые реализации виртуальных методов в производных классах.

Запечатанные классы и члены классов

Классы могут быть объявлены как запечатанные путем помещения ключевого слова sealed перед определением класса. Например:

public sealed class D
{
    // Class members here.
}

Запечатанный класс не может использоваться в качестве базового класса. Поэтому он также не может быть абстрактным классом. Запечатанные классы предотвращают наследование. Поскольку их нельзя использовать в качестве базовых классов, определенная оптимизация во время выполнения позволяет несколько ускорить вызов членов запечатанных классов.

Метод, индексатор, свойство или событие для производного класса, переопределяющего виртуальный член базового класса, может объявлять этот член как запечатанный. Это делает бесполезным виртуальный аспект члена для каждого последующего производного класса. Для этого в объявлении члена класса необходимо перед ключевым словом override поместить ключевое слово sealed. Например:

public class D : C
{
    public sealed override void DoWork() { }
}

См. также