C#. Запрет наследования. Ключевое слово sealed. Особенности применения. Пример

Запрет наследования. Ключевое слово sealed. Особенности применения. Пример


Содержание


Поиск на других ресурсах:




1. Ключевое слово sealed. Случаи применения

В языке C# введено ключевое слово sealed, которое используется в двух случаях:

  • когда нужно запретить наследование от некоторого класса. В многих иерархиях, классы, которые размещены на нижних уровнях могут быть обозначены как sealed;
  • когда нужно запретить переопределение некоторого метода в иерархии классов. Эта ситуация возможна, если в иерархии классов методы унаследованных классов переопределяют виртуальные методы базовых классов.

 

2. Применение ключевого слова sealed для класса. Общая форма. Пример

Общая форма использования ключевого слова sealed для класса, следующая:

sealed class ClassName
{
  // ...
}

где

  • ClassName – имя класса, который нужно запретить наследовать.

Если из класса ClassName попробовать унаследовать другой класс, то возникнет ошибка на этапе компиляции. При этом, сам класс ClassName может быть унаследован от другого класса.

Например, в следующем коде

// Класс, который запрещено наследовать
sealed class A
{
  // ...
}

// Класс, который пробует унаследовать класс A
class B : A
{
  // ...
}

компилятор выдаст ошибку

'B': cannot derive from sealed type 'A'

 

3. Применение ключевого слова sealed для метода. Общая форма. Пример

Ключевое слово sealed может быть применено для метода также. Использование sealed для метода означает, что метод запрещено переопределять в унаследованных классах. Значит, такой метод должен быть объявлен с ключевым словом override. А это, в свою очередь, означает, что класс с sealed-методом должен наследовать другой базовый класс, который содержит метод с таким же именем.

Чтобы к методу класса применить ключевое слово sealed, нужно чтобы выполнялись следующие условия:

  • класс должен быть унаследован от другого (базового) класса;
  • в базовом классе должен быть объявлен метод, который переопределяется в данном (производном) классе. Этот метод базового класса также должен быть объявлен с ключевыми словами virtual или override (если базовый класс также унаследован).

Общая форма использования ключевого слова sealed для метода следующая:

class ClassName : BaseClassName
{
  // ...

  access_modifier sealed override MethodName(parameters)
  {
    // ...
  }
}

где

  • ClassName – имя класса, в котором объявлен sealed-метод с именем MethodName;
  • BaseClassName – имя класса, который есть базовым для класса ClassName. Запрет переопределения метода в классе предусматривает, что этот класс унаследован от другого базового класса, в котором объявлен одноименный переопределяемый метод. Поэтому, если для некоторого метода в классе нужно применить ключевое слово sealed, этот класс обязательно должен быть унаследован от другого класса;
  • access_modifier – один из модификаторов доступа public, protected, internal, protected internal. Модификатор доступа private не может быть применен к sealed-методу;
  • MethodName – имя метода, который объявляется как sealed. Данный метод должен быть объявлен с ключевым словом override. Это значит, что данный метод переопределяет одноименный метод базового класса BaseClassName.

Пример.

Объявляется иерархия классов A, B, C. В классе C объявляется метод, который запрещено переопределять.

// Базовый класс для классов B, C
class A
{
  // Метод, который переопределяется в производных классах
  public virtual void Method()
  {
    Console.WriteLine("MethodA()");
  }
}

// Класс, который наследует класс A
class B : A
{
  // В этом классе объявляется метод, который не запрещено
  // переопределять в производных классах
  public override void Method()
  {
    Console.WriteLine("MethodB()");
  }
}

//
class C : B
{
  // Объявляется метод, который запрещено переопределять
  // в производных классах - с ключевым словом sealed
  public override sealed void Method()
  {
    Console.WriteLine("MethodC()");
  }
}

Если из класса C попробовать унаследовать класс D, и в классе D объявить метод, который переопределяет метод Method() класса C как показано далее

...

// Класс D наследует класс C
class D : C
{
  // Ошибка! Метод Method() нельзя переопределять
  public override void Method() // ошибка!
  {
    Console.WriteLine("MethodD()");
  }
}

...

то компилятор выдаст ошибку

D.Method(): cannot override inherited member C.Method() because it is sealed

Чтобы поправить ситуацию нужно выполнить одно из двух действий (в зависимости от поставленной задачи):

  • убрать слово sealed перед именем метода в классе C;
  • поменять слово override на слово new перед именем метода в классе D.

 

4. Можно ли в sealed-классе объявить sealed метод?

Да, можно. В приведенном ниже примере объявляется sealed-класс и sealed-метод в этом классе.

// Базовый класс
class A
{
  // ...

  // виртуальный метод
  protected virtual void Method()
  {

  }
}

// Класс, который наследует класс A
sealed class B : A
{
  // ...

  // метод, который переопределяет одноименный метод базового класса
  protected sealed override void Method()
  {

  }
}

Хотя класс B не может быть унаследован, компилятор такой код не запрещает.

 


Связанные темы

 


 

0
fb-share-icon20