Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Лекции ЛИПО .doc
Скачиваний:
0
Добавлен:
06.12.2018
Размер:
441.86 Кб
Скачать

Виртуальные методы

Объявляя функцию базового класса как 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 могут быть объявлены только нестати­ческие свойства и нестатические индексаторы. Никакие другие функции-члены не мо­гут быть виртуальными, а, значит, не могут быть переопределены.

class class1

{

public int a, b;

public class1()

{

Console.WriteLine("ВВедите числа");

a = Convert.ToInt32(Console.ReadLine());

b = Convert.ToInt32(Console.ReadLine());

}

public virtual void sum(int c, int d)

{

int q = c + d;

Console.WriteLine("Сумма равна" + q);

}

}

class class2 : class1

{

public override void sum(int c, int d)

{

int q = c + 2 * d;

Console.WriteLine("Сумма равна" + q);

}

}

class Program

{

static void Main(string[] args)

{

class1 myClass1 = new class1();

class2 myClass2 = new class2();

myClass1.sum(myClass1.a, myClass1.b);

myClass2.sum(myClass2.a, myClass2.b);

Console.ReadLine();

}

}