Наследование конструкторов

Наследование конструкторов

Правила наследования конструкторов - достаточно сложные. В разных языках программирования приняты разные решения на этот счет. В частности, в Delphi Object Pascal все конструкторы наследуются. В .NET, напротив, конструкторы не наследуются. Причина такого решения - каждый класс сам должен отвечать за инициализацию своих экземпляров. Единственное исключение в .NET - если класс вовсе не определяет конструкторов, то автоматически генерируется конструктор без параметров, называемый конструктором по умолчанию.

В PascalABC.NET принято промежуточное решение. Если класс не определяет конструкторов, то все конструкторы предка автоматически генерируются в потомке, вызывая соответствующие конструкторы предка (можно также говорить, что они наследуются). Если в классе определяются конструкторы, то конструкторы предка не генерируются. Конструктор по умолчанию, если он явно не определен, генерируется автоматически в любом случае и является protected.

Кроме того, в .NET обязательно в конструкторе потомка первым оператором должен быть вызван конструктор предка; в Object Pascal это необязательно. Если в PascalABC.NET конструктор предка вызывается из конструктора потомка, то этот вызов должен быть первым оператором. Если конструктор предка явно не вызывается из конструктора потомка, то неявно первым оператором в конструкторе потомка вызывается конструктор предка по умолчанию (т.е. без параметров). Если такого конструктора у предка нет (это может быть класс, откомпилированный другим .NET-компилятором или входящий в стандартную библиотеку классов - все классы, откомпилированные PascalABC.NET, имеют конструктор по умолчанию), то возникает ошибка компиляции.

Например:

type

A = class

i: integer;

// конструктор по умолчанию не определен явно, поэтому генерируется автоматически

constructor Create(i: integer);

begin

Self.i := i;

end;

end;

B = class(A)

j: integer;

constructor Create;

begin

// конструктор по умолчанию базового класса вызывается автоматически

// конструктор по умолчанию определен явно, поэтому не генерируется автоматически

j := 1;

end;

constructor Create(i,j: integer);

begin

inherited Create(i);

Self.j := j;

end;

end;

C = class(B)

// класс не определяет конструкторов, поэтому

// конструктор по умолчанию и constructor Create(i,j: integer)

// генерируются автоматически, вызывая в своем теле соответствующие конструкторы предка

end;