Volatile 19 страница
class A class B: A Инициализатор конструктора экземпляров не может иметь доступ к создаваемому экземпляру. Поэтому ссылка на this в выражении аргумента инициализатора конструктора, как и ссылка в выражении аргумента на любой член экземпляра посредством простого_имени;, является ошибкой времени компиляции. 10.11.2 Инициализаторы переменных экземпляров Если у конструктора экземпляра нет инициализатора конструктора или есть инициализатор конструктора вида base(...), этот конструктор неявно выполняет инициализации, указанные инициализаторами_переменных; полей экземпляра, объявленных в его классе. Это соответствует последовательности присваиваний, выполняемых непосредственно после входа в конструктор и перед неявным вызовом конструктора прямого базового класса. Инициализаторы переменных выполняются в текстовом порядке их появления в объявлении класса. 10.11.3 Выполнение конструктора Инициализаторы переменных преобразуются в операторы присваивания, и эти операторы присваивания выполняются перед вызовом конструктора экземпляров базового класса. Этот порядок обеспечивает инициализацию всех полей экземпляра их инициализаторами переменных до выполнения каких-либо операторов, имеющих доступ к этому экземпляру. Пример. using System; class A public virtual void PrintFields() {} } class B: A public B() { public override void PrintFields() { В этом примере, если new B() используется для создания экземпляра B, создается следующий вывод: x = 1, y = 0 Значение x равно 1, потому что инициализатор переменной выполняется до вызова конструктора экземпляров базового класса. Однако значение y равно 0 (значение по умолчанию для int), потому что присваивание для y выполняется только после возврата из конструктора базового класса. Полезно считать инициализаторы переменных экземпляра операторами, которые автоматически вставляются перед телом_конструктора. Пример. using System; class A public A() { public A(int n) { class B: A public B(): this(100) { public B(int n): base(n – 1) { В этом примере содержится несколько инициализаторов переменных, а также содержатся инициализаторы конструкторов обоих видов (base и this). Этот пример соответствует коду, показанному ниже, где каждый комментарий указывает автоматически вставляемый оператор (синтаксис, используемый для автоматически вставляемых вызовов конструктора не является допустимым, а служит только для пояснения механизма). using System.Collections; class A public A() { public A(int n) { class B: A public B(): this(100) { public B(int n): base(n – 1) { 10.11.4 Конструкторы по умолчанию Если класс не содержит объявления конструкторов экземпляров, автоматически предоставляется конструктор экземпляров по умолчанию. Этот конструктор по умолчанию просто вызывает не имеющий параметров конструктор прямого базового класса. Если в прямом базовом классе нет доступного конструктора экземпляров, не имеющего параметров, возникает ошибка времени компиляции. Если класс абстрактный, то объявленная доступность для конструктора по умолчанию защищена. Иначе объявленная доступность для конструктора по умолчанию является общей. Таким образом, конструктор по умолчанию всегда имеет вид protected C(): base() {} или public C(): base() {} где C – это имя класса. Пример. class Message В этом примере предоставлен конструктор по умолчанию, так как класс не содержит объявлений конструкторов экземпляров. Так, этот пример в точности эквивалентен следующему: class Message public Message(): base() {} 10.11.5 Закрытые конструкторы; Если в классе T объявлены только закрытые конструкторы экземпляров, для классов вне программного текста T невозможно вывести из T или непосредственно создать экземпляры T. Поэтому, если класс содержит только статические члены и не предназначен для создания экземпляров, добавление пустого закрытого конструктора экземпляров предотвратит создание экземпляров. Пример. public class Trig public const double PI = 3.14159265358979323846; public static double Sin(double x) {...} Класс Trig группирует связанные методы и константы, но не предназначен для создания экземпляров. Поэтому он объявляет единственный пустой закрытый конструктор экземпляров. По крайней мере один конструктор экземпляров должен быть объявлен, чтобы запретить автоматическое создание конструктора по умолчанию. 10.11.6 Необязательные параметры конструктора экземпляров Вид this(...) инициализатора конструктора обычно используется в сочетании с перегрузкой для реализации необязательных параметров конструктора экземпляров. Пример. class Text public Text(int x, int y): this(x, y, null) {} public Text(int x, int y, string s) { В этом примере первые два конструктора экземпляров только предоставляют значения по умолчанию для отсутствующих аргументов. Оба используют инициализатор конструктора this(...) для вызова третьего конструктора экземпляров, который действительно выполняет работу по инициализации нового экземпляра. Это действие соответствует действию необязательных параметров конструктора: Text t1 = new Text(); // Same as Text(0, 0, null) 10.12 Статические конструкторы Статический конструктор – это член, реализующий действия, необходимые для инициализации закрытого типа класса. Статические конструкторы объявляются с помощью объявлений_статического_конструктора;: объявление_статического_конструктора:
|