// Класс PTSalesPerson не сможет быть базовым классом.
public sealedclass PTSalesPerson: SalesPerson {
public PTSalesPerson(string fullName, int age, int empID, float currPay, string ssn, int numbOfSales): base (fullName , age, empID, currPay, ssn, numbOfSales) {
// Логика конструктора…
}
// Другие члены…
}
Поскольку класс PTSalesPerson изолирован, он не может служить базовым Классам никакому другому типу. Поэтому при попытке расширить PTSalesPersоn вы получите сообщение об ошибке компиляции.
// Ошибка компиляции!
public class ReallyPTSalesPerson: PTSalesPerson{…}
Наиболее полезным ключевое слово sealed оказывается при создании автономных классов утилит. Класс String, определённый в пространстве имен Sуstem, например, явно изолирован.
public sealedclass string: object, IComparable, ICloneable, IConvertible, IEnumerable {…}
Поэтому вы не сможете создать новый класс, производный от System.String:
// Снова ошибка!
public class MyString: string
Если вы хотите создать новый класс, использующий функциональные возможности изолированного класса, единственным вариантом будет отказ от классического наследования и использование модели локализации/делегирования (известной еще как отношение локализации, "has-a").
Модель локализации/делегирования
Как уже отмечалось в этой главе, наследование можно реализовать двумя способами. Только что мы исследовали классическое отношение подчиненности ("is-a"). Чтобы завершить обсуждение второго принципа ООП, давайте рассмотрим отношение локализации (отношение "has-a", также известное под названием модели локализации/делегирования). Предположим, что мы создали новый класс, моделирующий пакет льгот работника.
// Этот тип будет функционировать, как вложенный класс.
public class BenefitPackage {
// Другие члены, представляющие пакет страховок,
// медицинского обслуживания и т.д.
public double ComputePayDeduction() {return 125.0;}
}
Ясно, что отношение подчиненности ("is-a") между типами BenefitPackage (пакет льгот) и Employee (работник) выглядело бы достаточно странно. (Является ли менеджер пакетом льгот? Вряд ли.) Но должно быть ясно и то, что какая-то связь между этими типами необходима. Короче, вы должны выразить ту идею, что каждый работник имеет ("has-a") пакет льгот. Для этого определение класса Employee следует обновить так", как показано ниже.
// Работники теперь имеют льготы.
public class Employee {
…
// Содержит объект BenefitPackage.
protected BenefitPackage empBenefits = new BenefitPackage();
}
Здесь вы успешно создали вложенный объект. Но чтобы открыть функциональные возможности вложенного объекта внешнему миру, требуется делегирование. Делегирование означает добавление в класс-контейнер таких членов, которые будут использовать функциональные возможности содержащегося в классе объекта. Например, можно изменить класс Employee так, чтобы он открывал содержащийся в нем объект empBenefits с помощью некоторого свойства, а также позволял использовать функциональные возможности этого объекта с помощью нового метода GetBenefitCost().
public class Employee {
protected BenefitPackage empBenefits = new BenefitPackage();
// Открытие некоторых функциональных возможностей объекта.
public double GetBenefitCost() {
return empBenefits.ComputePayDeduction();
}
// Доступ к объекту через пользовательское свойство.
public BenefitPackage Benefits {
get {return empBenefits;}
set {empBenefits = value;}
}
}
В следующем обновленном методе Main() обратите внимание на то, как можно взаимодействовать с внутренним типом BenefitsPackage, определяемым типом Employee.
static void Main(string[] args) {
Manager mel;
mel = new Manager();
Console.WriteLine (mel. Benefits.ComputerPayDeduction());
…
Consolе.ReadLine();
}
Вложенные определения типов
Перед тем как рассмотреть заключительный принцип ООП (полиморфизм), давайте обсудим технику программирования, называемую вложением типов . В C# можно определить тип (перечень, класс, интерфейс, структуру или делегат) в пределах области видимости класса или структуры. При этом вложенный ("внутренний") тип считается членом содержащего его ("внешнего") класса, с точки зрения среды выполнения ничем не отличающимся от любого другого члена (поля, свойства, метода, события и т.п.). Синтаксис, используемый для вложения типа, исключительно прост.
Читать дальше