Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Лек_ООП_2_8 - 2_9 Реалізація поліморфізму та Ш...doc
Скачиваний:
0
Добавлен:
01.03.2025
Размер:
290.82 Кб
Скачать

Тема 2.8. Виртуальные функции в c#

Что такое «Виртуальные функции»? 1

Как объявляются виртуальные функции? 4

Абстрактные функции и абстрактные классы 4

Модификатор sealed 6

Реализация виртуального механизма 7

Наследование и универсальность 7

Синтаксис универсального класса 8

Класс с универсальными методами 8

Два основных механизма объектной технологии 8

Ограниченная универсальность 12

Синтаксис ограничений 12

Родовое порождение класса 14

Универсальные структуры 14

Универсальные интерфейсы 14

Универсальные делегаты 14

Framework .Net и универсальность 15

В этой лекции рассматриваются приемы управления передачей свойств при наследовании.

С помощью модификаторов virtual, override, abstract и sealed можно разрешать или запрещать переопределение функций, делать переобъявление обязательным, запрещать использование родительских функций и производство наследников.

Что такое «Виртуальные функции»?

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

class Square

{ protected double x=10; // Сторона, (мм)

public void Print_S(){ Console.WriteLine("Площадь = {0:F3}", Area());}

protected virtual double Area(){ return x * x; }

}

class Rhumb : Square

{ double a=Math.PI/4; // Угол, (рад)

protected override double Area() { return x * x * Math.Sin(a); }

}

class Program

{ static void Main()

{ Rhumb r1 = new Rhumb();

r1.Print_S();

Console.ReadKey();

}

}

Зачем нужны виртуальные функции?

Без них невозможно строить иерархию классов с «отложенными на потом» действиями.

Например, в базовом классе «подвижный объект» из предыдущей лекции может быть определена функция NewPoz, которая определяет изменение положения объекта под действием силы. Для этого определение изменения положения нужно знать, сколько прошло времени и как за это время под действием силы изменилась скорость. Для этого служит функция того же базового класса VarSpeed, вычисляющая скорость объекта.

Однако на алгоритм вычисления скорости влияют особенности объектов: ограничения на пространство движения, учет массы груза. Поэтому функция VarSpeed должна переобъявляться практически в каждом дочернем классе. Если она не виртуальна, то и функцию NewPoz придется дублировать (переобъявлять) в каждом дочернем классе, чтобы каждая ее копия могла вызывать «свою» VarSpeed. Это неудобно, и нарушает принципы ООП.

Если сделать функцию VarSpeed виртуальной, то вместо переобъявления, которое скрывает родительский метод, можно сделать переопределение, т.е. обеспечить автоматическую подстановку новой функции вместо старой выше по иерархии.

В этом случае диаграмма классов станет несколько проще:

Как объявляются виртуальные функции?

Для этого перед ними в базовом классе ставится ключевое слово virtual. В дочерних классах ставится слово override.

Теперь функция NewPoz объявлена только в классе «движущийся объект» и нигде не дублируется. Поэтому при вычислении позиции некоторого объекта из класса «Грузовой автомобиль», вызов функции VarSpeed будет происходить по следующей схеме:

Примечание

Виртуальная функция не может быть закрытой (private).

Виртуальная функция не может быть статической (static).