Книга: Описание языка PascalABC.NET
Наследование конструкторов
Наследование конструкторов
Правила наследования конструкторов - достаточно сложные. В разных языках программирования приняты разные решения на этот счет. В частности, в 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;
- Обзор классов и объектов
- Видимость членов класса и модификаторы доступа
- Методы
- Инициализаторы полей
- Конструкторы
- Предварительное объявление классов
- Переменная Self
- Свойства
- Индексные свойства
- Наследование
- Переопределение методов
- Наследование конструкторов
- Виртуальные методы и полиморфизм
- Абстрактные методы
- Перегрузка операций
- Классовые поля, методы и конструкторы
- Методы расширения
- Анонимные классы
- Автоклассы
- ГЛАВА 11 Наследование
- Порядок вызова конструкторов
- Конструкторы и наследование
- 11.1.1. Применение нескольких конструкторов
- Перегрузка конструкторов
- У14.4 Наследование без классов
- Наследование
- Лекция 9. Наследование и замыкание
- Лекция 14. Введение в наследование
- Лекция 15. Множественное наследование
- Дублируемое наследование
- Единичное наследование (single inheritance)