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