// В этом классе метод Who() не переопределяется.
}
class Derived3 : Derived2 {
//Ив этом классе метод Who() не переопределяется.
}
class No0verrideDemo2 { static void Main() {
Derived3 dOb = new Derived3();
Base baseRef; // ссылка на базовый класс
baseRef = dOb;
baseRef.Who(); // вызов метода Who() из класса Derivedl
}
}
Вот к какому результату приводит выполнение этого кода.
Метод Who() в классе Derivedl
В данном примере класс Derived3 наследует класс Derived2, который наследует класс Derivedl, а тот, в свою очередь, — класс Base. Как показывает приведенный выше результат, выполняется метод Who () , переопределяемый в классе Derivedl, поскольку это первый вариант виртуального метода, обнаруживаемый при продвижении вверх по иерархии от классов Derived3 и Derived2, где метод Who () не переопределяется, к классу Derivedl.
И еще одно замечание: свойства также подлежат модификации ключевым словом virtual и переопределению ключевым словом override. Это же относится и к индексаторам.
Что дает переопределение методов
Благодаря переопределению методов в C# поддерживается динамический полиморфизм. В объектно-ориентированном программировании полиморфизм играет очень важную роль, потому что он позволяет определить в общем классе методы, которые становятся общими для всех производных от него классов, а в производных классах — определить конкретную реализацию некоторых или же всех этих методов. Переопределение методов — это еще один способ воплотить в C# главный принцип полиморфизма: один интерфейс — множество методов.
Удачное применение полиморфизма отчасти зависит от правильного понимания той особенности, что базовые и производные классы образуют иерархию, которая продвигается от меньшей к большей специализации. При надлежащем применении базовый класс предоставляет все необходимые элементы, которые могут использоваться в производном классе непосредственно. А с помощью виртуальных методов в базовом классе определяются те методы, которые могут быть самостоятельно реализованы в производном классе. Таким образом, сочетая наследование с виртуальными методами, можно определить в базовом классе общую форму методов, которые будут использоваться во всех его производных классах.
Применение виртуальных методов
Для того чтобы стали понятнее преимущества виртуальных методов, применим их в классе TwoDShape. В предыдущих примерах в каждом классе, производном от класса TwoDShape, определялся метод Area (). Но, по-видимому, метод Area () лучше было бы сделать виртуальным в классе TwoDShape и тем самым предоставить возможность переопределить его в каждом производном классе с учетом особенностей расчета площади той двумерной формы, которую инкапсулирует этот класс. Именно это и сделано в приведенном ниже примере программы. Ради удобства демонстрации классов в этой программе введено также свойство паше в классе TwoDShape.
// Применить виртуальные методы и полиморфизм-.
using System;
class TwoDShape { double pri_width; double pri_height;
// Конструктор по умолчанию, public TwoDShape() {
Width = Height = 0.0; name = 'null';
}
// Параметризированный конструктор.'
public TwoDShape(double w, double h, string n) {
Width = w;
Height = h; name = n;
}
// Сконструировать объект равной ширины и высоты, public TwoDShape(double х, string n) {
