Но переопределять виртуальный метод совсем не обязательно. Ведь если в производном классе не предоставляется собственный вариант виртуального метода, то используется его вариант из базового класса, как в приведенном ниже примере.
/* Если виртуальный метод не переопределяется, то используется его вариант из базового класса. */
using System;
class Base {
// Создать виртуальный метод в базовом классе.
public virtual void Who() {
Console.WriteLine("Метод Who() в классе Base");
}
}
class Derivedl : Base {
// Переопределить метод Who() в производном классе.
public override void Who() {
Console.WriteLine("Метод Who() в классе Derivedl");
}
}
class Derived2 : Base {
// В этом классе метод Who() не переопределяется.
}
class NoOverrideDemo {
static void Main() {
Base baseOb = new Base();
Derivedl dObl = new Derivedl();
Derived2 d0b2 = new Derived2();
Base baseRef; // ссылка на базовый класс
baseRef = baseOb;
baseRef.Who();
baseRef = dObl;
baseRef.Who() ;
baseRef = d0b2;
baseRef.Who(); // вызывается метод Who() из класса Base
}
}
Выполнение этого кода приводит к следующему результату.
Метод Who() в классе Base.
Метод Who() в классе Derivedl
Метод Who() в классе Base
В данном примере метод Who()
не переопределяется в классе Derived2
. Поэтому для объекта класса Derived2
вызывается метод Who()
из класса Base.
Если при наличии многоуровневой иерархии виртуальный метод не переопределяется в производном классе, то выполняется ближайший его вариант, обнаруживаемый вверх по иерархии, как в приведенном ниже примере.
/* В многоуровневой иерархии классов выполняется тот переопределенный вариант виртуального метода, который обнаруживается первым при продвижении вверх по иерархии. */
using System;
class Base {
// Создать виртуальный метод в базовом классе,
public virtual void Who() {
Console.WriteLine("Метод Who() в классе Base");
}
}
class Derived1 : Base {
// Переопределить метод Who() в производном классе.
public override void Who() {
Console.WriteLine("Метод Who() в классе Derived1");
}
}
class Derived2 : Derived1 {
// В этом классе метод Who() не переопределяется.
}
class Derived3 : Derived2 {
//И в этом классе метод Who() не переопределяется.
}
class No0verrideDemo2 {
static void Main() {
Derived3 dOb = new Derived3();
Base baseRef; // ссылка на базовый класс
baseRef = dOb;
baseRef.Who(); // вызов метода Who() из класса Derivedl
}
}
Вот к какому результату приводит выполнение этого кода.
Метод Who() в классе Derived1
В данном примере класс Derived3
наследует класс Derived2
, который наследует класс Derived1
, а тот, в свою очередь, — класс Base
. Как показывает приведенный выше результат, выполняется метод Who()
, переопределяемый в классе Derived1
, поскольку это первый вариант виртуального метода, обнаруживаемый при продвижении вверх по иерархии от классов Derived3
и Derived2
, где метод Who()
не переопределяется, к классу Derived1
.
И еще одно замечание: свойства также подлежат модификации ключевым словом virtual
и переопределению ключевым словом override
. Это же относится и к индексаторам.