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

 


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