Главная arrow Язык программирования C# arrow C# Полное руководство Герберт Шилдт arrow Вызов конструкторов базового класса C# Полное руководство Герберт Шилдт

Вызов конструкторов базового класса C# Полное руководство Герберт Шилдт

С помощью формы расширенного объявления конструктора производного класса и ключевого слова base в производном классе может быть вызван конструктор, определенный в его базовом классе. Ниже приведена общая форма этого расширенного объявления.
   конструктор_производного_класса (
              список_параметров) : base {список_аргументов) {
         // тело конструктора
   }

где список_аргументов обозначает любые аргументы, необходимые конструктору в базовом классе. Обратите внимание на местоположение двоеточия.
Для того чтобы продемонстрировать применение ключевого слова base на конкретном примере, рассмотрим еще один вариант класса TwoDShape в приведенной ниже программе. В данном примере определяется конструктор, инициализирующий свойства Width и Height. Затем этот конструктор вызывается конструктором класса Triangle.

// Добавить конструктор в класс TwoDShape.

using System;

// Класс для двумерных объектов.
class TwoDShape {
   double pri_width;
   double pri_height;

   // Конструктор класса TwoDShape.
   public TwoDShape(double w, double h) {
      Width = w;
      Height = h;
   }

   // Свойства ширины и высоты объекта.
   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;

   // Вызвать конструктор базового класса.
   public Triangle(
              string s, double w, double h) : base (w, h) {
      Style = s;
   }

   // Возвратить площадь треугольника.
   public double Area() {
      return Width * Height / 2;
   }

   // Показать тип треугольника.
   public void ShowStyle() {
      Console.WriteLine("Треугольник " + Style);
   }
}

class Shapes4 {
   static void Main() {
      Triangle t1 = new Triangle("равнобедренный", 4.0, 4.0);
      Triangle t2 = new Triangle("прямоугольный", 8.0, 12.0);
      Console.WriteLine("Сведения об объекте t1: ");
      t1.ShowStyle();
      t1.ShowDim();
      Console.WriteLine("Площадь равна " + t1.Area());
      
      Console.WriteLine();

      Console.WriteLine("Сведения об объекте t2 : ");
      t2.ShowStyle();
      t2.ShowDim();
      Console.WriteLine("Площадь равна " + t2.Area());
   }
}


Теперь конструктор класса Triangle объявляется следующим образом:

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

В данном варианте конструктор Triangle () вызывает метод base с параметрами w и h. Это, в свою очередь, приводит к вызову конструктора TwoDShape (), инициализирующего свойства Width и Height значениями параметров w и h. Они больше не инициализируются средствами самого класса Triangle, где теперь остается инициализировать только его собственный член Style, определяющий тип треугольника. Благодаря этому класс TwoDShape высвобождается для конструирования своего по-добъекта любым избранным способом. Более того, в класс TwoDShape можно ввести функции, о которых даже не будут подозревать производные классы, что предотвращает нарушение кода.
С помощью ключевого слова base можно вызвать конструктор любой формы, определяемой в базовом классе, причем выполняться будет лишь тот конструктор, параметры которого соответствуют переданным аргументам. В качестве примера ниже приведены расширенные варианты классов TwoDShape и Triangle, в которые включены как используемые по умолчанию конструкторы, так и конструкторы, принимающие один аргумент.

// Добавить дополнительные конструкторы
//в класс TwoDShape.

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("Ширина и высота равны " +
                               Widths+" и " + 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);
   }
}

class Shapes5 {
   static void Main() {
      Triangle t1 = new Triangle();
      Triangle t2 = new Triangle("прямоугольный", 8.0, 12.0);
      Triangle t3 = new Triangle(4.0);

      t1 = t2;

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

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

      Console.WriteLine ();

      Console.WriteLine("Сведения об объекте t2: ");
      t2.ShowStyle();
      t2.ShowDim();
      Console.WriteLine("Площадь равна " + t2.Area());

      Console.WriteLine() ;

      Console.WriteLine("Сведения об объекте t3: ");
      t3.ShowStyle();
      t3.ShowDim();
      Console.WriteLine("Площадь равна " + t3.Area());

      Console.WriteLine();
   }
}

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

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

   Сведения об объекте t3:
   Треугольник равнобедренный
   Ширина и высота равны 4 и 4
   Площадь равна 8

А теперь рассмотрим вкратце основные принципы действия ключевого слова base. Когда в производном классе указывается ключевое слово base, вызывается конструктор из его непосредственного базового класса. Следовательно, ключевое слово base всегда обращается к базовому классу, стоящему в иерархии непосредственно над вызывающим классом. Это справедливо даже для многоуровневой иерархии классов. Аргументы передаются базовому конструктору в качестве аргументов метода base (). Если же ключевое слово отсутствует, то автоматически вызывается конструктор, используемый в базовом классе по умолчанию.