Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Ответы ООП не все.docx
Скачиваний:
7
Добавлен:
22.09.2019
Размер:
224.93 Кб
Скачать

Вопрос 9 Виртуальные функции virtual. Вызов базовых версий функций base.

Объявляя функцию базового класса как virtual, тем самым вы позволяете ее переопределять в классах-наследниках:

Допускается объявление свойства как virtual. Для виртуального или пере­менного свойства используется такой же синтаксис, что и для невиртуального за исключением ключевого слова virtual, добавляемого к определению.

Для простоты далее речь пойдет в основном о методах, хотя все это касается также свойств. Концепция лежащая в основе виртуальных функций С#, идентична стандартной концепции объектно-ориентированного программирования (ООП). Вы можете переопределить виртуальную функцию в классе-наследнике, и когда этот метод буде-вызван, то запустится его версия, относящаяся к соответствующему типу объекта. С# по умолчанию функции не виртуальные, но (в отличие от конструкторов) могут быть явно объявлены как virtual. Это следует методологии C++: по причинам производительности функции не виртуальные, если это не указано явно. В отличие от этого, в Java все функции виртуальные. С# имеет отличающийся от C++ синтаксис поскольку требует явного объявления, когда функция класса-наследника переопреде­ляет другую функцию, с помощью ключевого слова overridde.

Этот синтаксис переопределения метода исключает потенциальные ошибки вре­мени выполнения, которые могут легко возникать в C++, когда сигнатура метода в классе-наследнике нечаянно оказывается отличной от базовой версии, в результате чего метод наследника не может переопределить базовый. В С# это всплывает в виде ошибки компиляции, поскольку компилятор легко обнаруживает метод, для которого указан модификатор override, но при этом не имеющий базового метода, который он переопределяет.

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

Синтаксический блок ::=

class <Идентификатор_базового_класса>

{

<Спецификатор_доступности> virtual <Тип__возвр_знач> <Идентификатор_метода> ([<Список_формальных параметров>])

{

< Операторы >

}

}

class <Идентификатор_производного_класса>

{

<Спецификатор_доступности> override <Тип_возвр_знач>

<Идентификатор_метода> ([<Список_формальных_парам>])

{

< Операторы >

}

}

<Спецификатор_доступности>::=

public

protected

internal

protected internal

Примечания.

  1. Виртуальный метод не может быть объявлен как private.

  2. Если метод в производном классе переопределяет метод базового класса, он дол­жен иметь то же имя и параметры (число и последовательность типов должны со­впадать), что и метод базового класса.

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

  4. Кроме нестатических методов, как virtual могут быть объявлены только нестати­ческие свойства и нестатические индексаторы. Никакие другие функции-члены не мо­гут быть виртуальными, а, значит, не могут быть переопределены.