Выбрать главу

Для того чтобы показать, насколько полезной может оказаться многоуровневая иерархия классов, рассмотрим следующий пример программы. В ней производный класс Triangle служит в качестве базового для создания другого производного класса — ColorTriangle. При этом класс ColorTriangle наследует все характерные особенности, а по существу, члены классов Triangle и TwoDShape, к которым добавляется поле color, содержащее цвет треугольника.

// Пример построения многоуровневой иерархии классов.

using System;

class TwoDShape { double pri_width; double pri_height;

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

Width = Height = 0.0;

}

// Конструктор для класса TwoDShape. public TwoDShape(double w, double h) {

Width = w;

Height = h;

}

// Сконструировать объект равной ширины и высоты, public TwoDShape(double х) {

Width = Height = x;

}

// Свойства ширины и высоты объекта, 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 void ShowDim() {

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

Width + " и " + Height);

}

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

string Style; // закрытый член класса

/* Конструктор, используемый по умолчанию.

Автоматически вызывает конструктор, доступный по умолчанию в классе TwoDShape. */ public Triangle ()    {

Style = "null";

}

// Конструктор.

public Triangle(string s, double w, double h) : base(w, h) { Style = s;

}

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

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

}

// Возвратить площадь треугольника, public double Area() {

return Width * Height / 2;

}

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

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

}

}

// Расширить класс Triangle, class ColorTriangle : Triangle { string color;

fc

public ColorTriangle(string c, string s,

double w, double h) : base(s, w, h) {

color = c;

}

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

Console.WriteLine("Цвет " + color);

}

}

class Shapes6 {

static void Main() {

ColorTriangle tl =

new ColorTriangle("синий", "прямоугольный", 8.0, 12.0); ColorTriangle t2 =

new ColorTriangle("красный", "равнобедренный", 2.0, 2.0);

Console.WriteLine("Сведения об объекте tclass="underline" "); tl.ShowStyle(); tl. ShowDinv() ; tl.ShowColor ();

Console .WriteLine ("Площадь равна " + tl.AreaO);

Console.WriteLine () ;

Console.WriteLine("Сведения об объекте t2: "); t2.ShowStyle(); t2.ShowDim(); t2.ShowColor() ;

Console.WriteLine("Площадь равна " + t2.Area());

}

}

При выполнении этой программы получается следующей результат.

Сведения об объекте tclass="underline"

Треугольник прямоугольный Ширина и высота равны 8 и 12 Цвет синий Площадь равна 48

Сведения об объекте t2:

Треугольник равнобедренный Ширина и высота равны 2 и 2 Цвет красный Площадь равна 2

Благодаря наследованию в классе ColorTriangle могут использоваться определенные ранее классы Triangle и TwoDShape, к элементам которых добавляется лишь та информация, которая требуется для конкретного применения данного класса. В этом отчасти и состоит ценность наследования, поскольку оно допускает повторное использование кода.

Приведенный выше пример демонстрирует еще одно важное положение: ключевое слово base всегда обозначает ссылку на конструктор ближайшего по иерархии базового класса. Так, ключевое слово base в классе ColorTriangle обозначает вызов конструктора из класса Triangle, а ключевое слово base в классе Triangle — вызов конструктора из класса TwoDShape. Если же в иерархии классов конструктору базового класса требуются параметры, то все производные классы должны предоставлять эти параметры вверх по иерархии, независимо от того, требуются они самому производному классу или нет.