Книга: C# 4.0: полное руководство

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

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

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

Для того чтобы показать, насколько полезной может оказаться многоуровневая иерархия классов, рассмотрим следующий пример программы. В ней производный класс 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 x) {
    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;
  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());
  }
}

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

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

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

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

Оглавление книги


Генерация: 1.213. Запросов К БД/Cache: 3 / 1
поделиться
Вверх Вниз