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 не може бути успадкований, компілятор такий код не забороняє.

  ⇑


Зв’язані теми

  ⇑