- •Глава 13. Включение, вложение и наследование классов
- •13.1. Включение объектов классов
- •13.2. Вложение классов
- •13.3. Наследование классов
- •13.4. Доступность членов класса при наследовании
- •13.5. Методы при наследовании
- •13.6. Абстрактные методы и абстрактные классы.
- •13.7. Опечатанные классы и методы
- •13.8. Применение абстрактых классов
13.2. Вложение классов
В объявление класса в качестве его члена может войти объявление типа. Таким типом может быть класс. Этот внутренний класс называют вложенным классом, а включающий его класс - внешним. Особенностью вложенного класса является то, что ему доступны все члены внешнего класса, даже если эти члены закрытые (private). Обычно вложенный класс вводится только для выполнения действий внутри внешнего класса и "не виден" вне включающего его класса. Однако, вложенный класс может быть объявлен с модификатором public и тогда он становится доступен везде, где виден внешний класс. Если открытый класс Nested вложен в класс Outside, то для внешнего обращения к вложенному классу следует использовать квалифицированное имя Outside.Nested.
Продемонстрируем синтаксис вложения классов на примере класса окружность (Circle), центр которой представляет объект вложенного класса Point. Чтобы возможности внешнего класса Circle были близки к возможностям уже рассмотренных классов, реализующих композицию и агрегацию, сделаем вложенный класс Point открытым. В следующей программе объявлен указанный класс Circle с вложенным классом Point.
// 13_03.cs - вложение классов
class Circle {
// Закрытые поля:
double rad; // радиус окружности
Point centre = new Point(); // центр окружности
// свойство для радиуса окружности:
public double Rad { get { return rad; } set { rad = value; } }
// свойство для получения значения длины окружности:
public double Len { get { return 2 * rad * Math.PI; } }
// свойство для центра окружности:
public Point Centre { get { return centre; } set { centre = value; } }
public void display()
{
Console.WriteLine("Centre: X={0}, Y={1}; Radius={2}, Length={3,6:f2}", centre.X, centre.Y, this.rad, Len);
}
public class Point
{
double x, y;
public double X { get { return x; } set { x = value; } }
public double Y { get { return y; } set { y = value; } }
} // end of Point
} // end of Circle
public static void Main()
{
Circle rim = new Circle();
rim.Centre.X = 100;
rim.Centre.Y = 200;
rim.Rad = 30.0;
rim.display();
}
Результат выполнения программы:
Centre: X=100, Y=200; Radius=30, Length = 188,50
В классе Circle для инициализации поля center используется конструктор умолчания класса Point. Префикс "Circle." при этом не требуется применять, хотя его использование не приведёт к ошибке. То же самое относится и к обозначению типа свойства Centre. Нет явного определения конструкторов и во внешнем классе. Поэтому в методе Main() для создания объекта, ассоциированного со ссылкой rim, используется конструктор умолчания Circle(). Для обращения к свойствам, определяющим центр окружности, потребовалось использовать имена с двойной квалификацией: rim.Centre.X и rim.Centre.Y.
В отличие от композиции и агрегации при вложении классов внутренний класс (не только объект) не существует независимо от внешнего. На диаграмме классов вложенный класс изображается именно внутри внешнего.
