Добавить в цитаты Настройки чтения

Страница 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(&quot;Метод Who() в классе Base&quot;);</b>

<b>  }</b>

<b>}</b>

<b>class Derivedl : Base {</b>

<b>  // Переопределить метод Who() в производном классе.</b>

<b>  public override void Who() {</b>

<b>    Console.WriteLine(&quot;Метод Who() в классе Derivedl&quot;);</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>