Метод 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 {

get { return pri_width; }

set { pri_width = value < 0 ? -value : value; }

}

public double Height {

get { return pri_height; }

set -{ pri_height = value < 0 ? -value : value; }

}

public string name { get; set; }

public void ShowDim() {

Console.WriteLine("Ширина и высота равны " +

Width + " и " + Height);

}

public virtual double Area() {

Console.WriteLine("Метод Area() должен быть переопределен"); return 0.0;

}

}

// Класс для треугольников, производный от класса TwoDShape.

class Triangle : TwoDShape { string Style;

// Конструктор, используемый по умолчанию, public Triangle() {

Style = "null";

}

// Конструктор для класса Triangle, public Triangle(string s, double w, double h) : base (w, h, "треугольник") {

Style = s;

}

// Сконструировать равнобедренный треугольник, public Triangle(double x) : base(x, "треугольник") {

Style = "равнобедренный";

}

// Сконструировать копию объекта типа Triangle, public Triangle(Triangle ob) : base(ob) {

Style = ob.Style;

}

// Переопределить метод Area() для класса Triangle, public override double Area() { return Width * Height / 2;

}

// Показать тип треугольника, public void ShowStyle() {

Console.WriteLine("Треугольник " + Style);

}

I/ Класс для прямоугольников, производный от класса TwoDShape. class Rectangle : TwoDShape {

// Конструктор для класса Rectangle, public Rectangle(double w, double h) : base (w, h, "прямоугольник") { }

// Сконструировать квадрат, public Rectangle(double x) : base(x, "прямоугольник") { }

// Сконструировать копию объекта типа Rectangle, public Rectangle(Rectangle ob) : base(ob) { }

// Возвратить логическое значение true, если // прямоугольник окажется квадратом, public bool IsSquareO {

if(Width == Height) return true; return false;

}

// Переопределить метод Area() для класса Rectangle, public override double Area() { return Width * Height;

}

}

class DynShapes {

static void Main() {

TwoDShape[] shapes = new TwoDShape[5] ;

shapes[0] = new Triangle("прямоугольный", 8.0, 12.0); shapes[1] = new Rectangle(10);

shapes[2] = new Rectangle(10, 4);

shapes[3] = new Triangle(7.0);

shapes[4] = new TwoDShape(10, 20, "общая форма");

for (int i=0; i < shapes.Length; i++) {

Console.WriteLine("Объект — " + shapes[i].name);

Console.WriteLine("Площадь равна " + shapes[i].Area());

Console.WriteLine();

}

}

}

Наши рекомендации