Конструкторы и наследование
86C# --- Руководство по C# --- Конструкторы и наследование
В иерархии классов допускается, чтобы у базовых и производных классов были свои собственные конструкторы. В связи с этим возникает следующий резонный вопрос: какой конструктор отвечает за построение объекта производного класса: конструктор базового класса, конструктор производного класса или же оба? На этот вопрос можно ответить так: конструктор базового класса конструирует базовую часть объекта, а конструктор производного класса — производную часть этого объекта. И в этом есть своя логика, поскольку базовому классу неизвестны и недоступны любые элементы производного класса, а значит, их конструирование должно происходить раздельно.
Если конструктор определен только в производном классе, то все происходит очень просто: конструируется объект производного класса, а базовая часть объекта автоматически собирается его конструктором, используемым по умолчанию.
Когда конструкторы определяются как в базовом, так и в производном классе, процесс построения объекта несколько усложняется, поскольку должны выполняться конструкторы обоих классов. В данном случае приходится обращаться к ключевому слову base, которое находит двоякое применение: во-первых, для вызова конструктора базового класса; и во-вторых, для доступа к члену базового класса, скрывающегося за членом производного класса.
С помощью формы расширенного объявления конструктора производного класса и ключевого слова base в производном классе может быть вызван конструктор, определенный в его базовом классе. Ниже приведена общая форма этого расширенного объявления:
конструктор_производного_класса(список_параметров) : base (список_аргументов) { // тело конструктора }
где список_аргументов обозначает любые аргументы, необходимые конструктору в базовом классе. Обратите внимание на местоположение двоеточия.
Давайте рассмотрим пример:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace ConsoleApplication1
{
class MyClass
{
public int x, y, z;
// Конструктор базового класса
public MyClass(int x, int y, int z)
{
this.x = x;
this.y = y;
this.z = z;
}
}
class ClassA : MyClass
{
int point;
// Конструктор производного класса
public ClassA(int point, int x, int y, int z)
: base(x, y, z)
{
this.point = point;
}
public void Pointer(ClassA obj)
{
obj.x *= obj.point;
obj.y *= obj.point;
obj.z *= obj.point;
Console.WriteLine("Новые координаты объекта: {0} {1} {2}", obj.x, obj.y, obj.z);
}
}
class Program
{
static void Main()
{
ClassA obj = new ClassA(10, 1, 4, 3);
Console.WriteLine("Координаты объекта: {0} {1} {2}", obj.x, obj.y, obj.z);
obj.Pointer(obj);
Console.ReadLine();
}
}
}

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