- •Обзор элементов класса.
- •Класс Object
- •Структуры
- •Методы Ссылочные параметры ref и out
- •Переменное число аргументов метода
- •Перегрузка методов. Вызов методов с одинаковым именем и разными аргументами
- •Конструкторы экземпляра
- •Вызов конструктора экземпляра
- •Закрытые конструкторы экземпляра
- •Статические конструкторы
- •Конструкторы структур
- •Член со спецификатором readonly
- •Деструкторы. Сборка мусора
- •Объект Account
- •Объект Account недоступен
- •Свойства
- •Индексаторы
- •Предпосылки появления наследования
- •Синтаксис наследования.
- •Типы наследования
- •Множественное наследование
- •Наследование интерфейса
- •Виртуальные методы
- •Спецификаторы доступности
- •Вызов базовых версий функций
- •Абстрактные классы и функции
- •Структуры и наследование
- •Полиморфизм
- •Потеря и восстановление информации о типе
- •Операции is и as
- •Файловый ввод-вывод
- •Потоки данных и файловый ввод-вывод
- •Виды файлов
- •Классы файлового ввода-вывода
- •Класс FileInfo
- •Текстовый ввод-вывод при помощи Stream Reader и Stream Writer
- •Бинарный ввод и вывод при помощи класса FileStream
Виртуальные методы
Объявляя функцию базового класса как virtual, тем самым вы позволяете ее переопределять в классах-наследниках:
Допускается объявление свойства как virtual. Для виртуального или переменного свойства используется такой же синтаксис, что и для невиртуального за исключением ключевого слова virtual, добавляемого к определению.
Для простоты далее речь пойдет в основном о методах, хотя все это касается также свойств. Концепция лежащая в основе виртуальных функций С#, идентична стандартной концепции объектно-ориентированного программирования (ООП). Вы можете переопределить виртуальную функцию в классе-наследнике, и когда этот метод буде-вызван, то запустится его версия, относящаяся к соответствующему типу объекта. С# по умолчанию функции не виртуальные, но (в отличие от конструкторов) могут быть явно объявлены как virtual. Это следует методологии C++: по причинам производительности функции не виртуальные, если это не указано явно. В отличие от этого, в Java все функции виртуальные. С# имеет отличающийся от C++ синтаксис поскольку требует явного объявления, когда функция класса-наследника переопределяет другую функцию, с помощью ключевого слова overridde.
Этот синтаксис переопределения метода исключает потенциальные ошибки времени выполнения, которые могут легко возникать в C++, когда сигнатура метода в классе-наследнике нечаянно оказывается отличной от базовой версии, в результате чего метод наследника не может переопределить базовый. В С# это всплывает в виде ошибки компиляции, поскольку компилятор легко обнаруживает метод, для которого указан модификатор override, но при этом не имеющий базового метода, который он переопределяет.
Ни поля-члены, ни статические функции не могут быть объявлены виртуальными. Эта концепция просто не имеет смысла ни для каких членов класса, за исключением функций-членов уровня экземпляра.
Синтаксический блок ::=
class <Идентификатор_базового_класса>
{
…
<Спецификатор_доступности> virtual <Тип__возвр_знач> <Идентификатор_метода> ([<Список_формальных параметров>])
{
< Операторы >
}
}
class <Идентификатор_производного_класса>
{
<Спецификатор_доступности> override <Тип_возвр_знач>
<Идентификатор_метода> ([<Список_формальных_парам>])
{
< Операторы >
}
…
}
<Спецификатор_доступности>::=
public
protected
internal
protected internal
Примечания.
-
Виртуальный метод не может быть объявлен как private.
-
Если метод в производном классе переопределяет метод базового класса, он должен иметь то же имя и параметры (число и последовательность типов должны совпадать), что и метод базового класса.
-
Переопределяющий метод должен иметь тот же спецификатор доступности и тип возвращаемого значения, что и переопределяемый метод базового класса.
-
Кроме нестатических методов, как 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();
}
}