Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
CSharp Language Specification.doc
Скачиваний:
12
Добавлен:
26.09.2019
Размер:
4.75 Mб
Скачать

10.1.4.1Базовые классы

Если тип_класса включен в базу_класса, он определяет прямой базовый класс объявленного класса. Если объявление класса не имеет базы_классы или база_класса перечисляет только типы интерфейса, прямым базовым классом считается object. Класс наследует члены из прямого базового класса (см. §10.3.3).

Рассмотрим пример:

class A {}

class B: A {}

В этом примере класс A считается прямым базовым классом для класса B, а класс B считается производным из класса A. Так как класс A не указывает явно прямой базовый класс, его неявным прямым базовым классом является object.

Для сформированного типа класса, если базовый класс указан в объявлении универсального класса, базовый класс сформированного типа получается путем замещения каждого параметра_типа в объявлении базового класса соответствующим аргументом_типа сформированного типа. При объявлении универсального класса

class B<U,V> {...}

class G<T>: B<string,T[]> {...}

базовый класс сформированного типа G<int> должен быть B<string,int[]>.

Прямой базовый класс типа класса должен быть не менее доступен, чем сам тип класса (§3.5.2). Например, если класс public произведен из класса private или internal, возникает ошибка времени компилирования.

Прямой базовый класс типа класса не должен быть одним из следующих типов: System.Array, System.Delegate, System.MulticastDelegate, System.Enum или System.ValueType. Кроме того, объявление универсального класса не может использовать System.Attribute в качестве прямого или непрямого базового класса.

При определении значения спецификации прямого базового класса A для класса B прямым базовым классом B временно считается object. Это означает, что значение спецификации базового класса не может рекурсивно зависеть от самого себя. Пример

class A<T> {

public class B{}

}

class C : A<C.B> {}

является ошибочным, поскольку в спецификации базового класса A<C.B> прямым базовым классом для C считается object, а следовательно (согласно правилам §3.8) считается, что C не содержит член B.

Базовыми классами типа класса являются прямой базовый класс и его базовые классы. Другими словами, набор базовых классов является транзитивным замыканием отношения прямого базового класса. Ссылаясь на пример выше, базовыми классами для класса B являются A и object. Рассмотрим пример.

class A {...}

class B<T>: A {...}

class C<T>: B<IComparable<T>> {...}

class D<T>: C<T[]> {...}

В этом примере базовыми классами D<int> являются C<int[]>, B<IComparable<int[]>>, A и object.

За исключением класса object, каждый тип класса имеет строго один прямой базовый класс. Класс object не имеет прямого базового класса и является окончательным базовым классом для всех других классов.

Если класс B производится из класса A, возникает ошибка времени компилирования, так как A зависит от B. Класс непосредственно зависит от его прямого базового класса (при его наличии) и от класса, в который он непосредственно вложен (при его наличии). С учетом этого определения, полным набором классов, от которых зависит класс, является рефлексивное и транзитивное замыкание отношения непосредственной зависимости.

Рассмотрим пример.

class A: A {}

Этот пример является ошибочным, поскольку класс зависит сам от себя. Аналогично, в примере

class A: B {}

class B: C {}

class C: A {}

имеется ошибка, поскольку классы циклически зависят сами от себя. Наконец, в примере

class A: B.C {}

class B: A { public class C {} }

имеется ошибка времени компилирования, так как класс A зависит от класса B.C (его прямой базовый класс), который зависит от класса B (его прямой заключающий класс), который зависит от класса A, создавая циклическую зависимость.

Обратите внимание, что класс не зависит от классов, вложенных в него. Рассмотрим пример.

class A { class B: A {} }

В этом примере B зависит от A (так как A является его прямым базовым классом и прямым заключающим классом), но A не зависит от B (так как B не является базовым классом и заключающим классом A). Поэтому пример является допустимым.

Невозможно выполнить создание производного класса от запечатанного класса sealed. В примере:

sealed class A {}

class B: A {} // Error, cannot derive from a sealed class

класс B является ошибочным, так как он пытается выполнить создание производного класса A из запечатанного класса sealed.

Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]