Чтение онлайн

ЖАНРЫ

C# 4.0 полное руководство - 2011

Шилдт Герберт

Шрифт:

}

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 Derivedl : Base {

// Переопределить метод Who в производном классе. public override void Who {

Console.WriteLine("Метод Who в классе Derivedl");

}

}

class Derived2 : Derivedl {

// В этом классе метод 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) {

Width = Height = x; name = n;

}

// Сконструировать копию объекта TwoDShape. public TwoDShape(TwoDShape ob) {

Width = ob.Width;

Height = ob.Height; name = ob.name;

}

// Свойства ширины и высоты объекта, public double Width {

Поделиться с друзьями: