// Содержит объект BenefitPackage.
protected BenefitPackage EmpBenefits = new BenefitPackage();
// Открывает доступ к некоторому поведению, связанному со льготами.
public double GetBenefitCost()
=> EmpBenefits.ComputePayDeduction();
// Открывает доступ к объекту через специальное свойство.
public BenefitPackage Benefits
{
get { return EmpBenefits; }
set { EmpBenefits = value; }
}
}
В показанном ниже обновленном коде верхнего уровня обратите внимание на взаимодействие с внутренним типом BenefitsPackage
Employee
:Console.WriteLine("***** The Employee Class Hierarchy *****\n");
...
Manager chucky = new Manager("Chucky", 50, 92, 100000, "333-23-2322", 9000);
double cost = chucky.GetBenefitCost();
Console.WriteLine($"Benefit Cost: {cost}");
Console.ReadLine();
Определения вложенных типов
В главе 5 кратко упоминалась концепция вложенных типов, которая является развитием рассмотренного выше отношения "имеет". В C# (а также в других языках .NET) допускается определять тип (перечисление, класс, интерфейс, структуру или делегат) прямо внутри области действия класса либо структуры. В таком случае вложенный (или "внутренний") тип считается членом охватывающего (или "внешнего") типа, и в глазах исполняющей системы им можно манипулировать как любым другим членом (полем, свойством, методом и событием). Синтаксис, применяемый для вложения типа, достаточно прост:
public class OuterClass
{
// Открытый вложенный тип может использоваться кем угодно.
public class PublicInnerClass {}
// Закрытый вложенный тип может использоваться
.
// только членами включающего класса
private class PrivateInnerClass {}
}
Хотя синтаксис довольно ясен, ситуации, в которых это может понадобиться, не настолько очевидны. Для того чтобы понять данный прием, рассмотрим характерные черты вложенных типов.
• Вложенные типы позволяют получить полный контроль над уровнем доступа внутреннего типа, потому что они могут быть объявлены как закрытые (вспомните, что невложенные классы нельзя объявлять с ключевым словом private
• Поскольку вложенный тип является членом включающего класса, он может иметь доступ к закрытым членам этого включающего класса.
• Часто вложенный тип полезен только как вспомогательный для внешнего класса и не предназначен для использования во внешнем мире.
Когда тип включает в себя другой тип класса, он может создавать переменные-члены этого типа, как в случае любого другого элемента данных. Однако если с вложенным типом нужно работать за пределами включающего типа, тогда его придется уточнять именем включающего типа. Взгляните на приведенный ниже код:
// Создать и использовать объект открытого вложенного класса. Нормально!
OuterClass.PublicInnerClass inner;
inner = new OuterClass.PublicInnerClass();
// Ошибка на этапе компиляции! Доступ к закрытому вложенному
// классу невозможен!
OuterClass.PrivateInnerClass inner2;
inner2 = new OuterClass.PrivateInnerClass();
Для применения такой концепции в примере с сотрудниками предположим, что определение BenefitPackage
Employee
:partial class Employee
{
public class BenefitPackage
{
// Предположим, что есть другие члены, представляющие
// медицинские/стоматологические программы и т.д.
public double ComputePayDeduction()
{
return 125.0;
}
}
...
}