Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Наследование.docx
Скачиваний:
0
Добавлен:
01.07.2025
Размер:
135.39 Кб
Скачать

11.5 Создание многоуровневой иерархии классов

В представленных до сих пор примерах программ использовались простые иерар­хии классов, состоявшие только из базового и производного классов. Но в С# мож­но также строить иерархии, состоящие из любого числа уровней наследования. Как упоминалось выше, многоуровневая иерархия идеально подходит для использования одного производного класса в качестве базового для другого производного класса. Так, если имеются три класса, А, В и С, то класс С может наследовать от класса В, а тот, в свою очередь, от класса А. В таком случае каждый производный класс наследует ха­рактерные особенности всех своих базовых классов. В частности, класс С наследует все члены классов В и А.

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

Листинг 11.13

// Многоуровневая иерархия классов.

using System;

class TwoDShape

{

double width;

double height;

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

public TwoDShape()

{

Width = Height = 0.0;

}

// Конструктор для класса TwoDShape.

public TwoDShape(double w, double h)

{

Width = w;

Height = h;

}

// Сконструировать объект равной ширины и высоты.

public TwoDShape(double x)

{

Width = Height = x;

}

// Свойства ширины и высоты объекта.

public double Width

{

get { return width; }

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

}

public double Height

{

get { return height; }

set { 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;

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 t1 =

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

ColorTriangle t2 =

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

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

t1.ShowStyle();

t1.ShowDim();

t1.ShowColor();

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

Console.WriteLine();

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

t2.ShowStyle();

t2.ShowDim();

t2.ShowColor();

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

}

}

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

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

Треугольник прямоугольный

Ширина и высота равны 8 и 12

Цвет синий

Площадь равна 48

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

Треугольник равнобедренный

Ширина и высота равны 2 и 2

Цвет красный

Площадь равна 2

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

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