Цель в том, чтобы создать семейство классов, моделирующих разнообразные типы сотрудников в компании. Предположим, что необходимо задействовать функциональность класса Employee при создании двух новых классов (SalesPerson и Manager). Новый класс SalesPerson "является" Employee (как и Manager). Вспомните, что в модели классического наследования базовые классы (вроде Employee) обычно применяются для определения характеристик, общих для всех наследников. Подклассы (такие как SalesPerson и Manager) расширяют общую функциональность, добавляя к ней специфическую функциональность.

В настоящем примере мы будем считать, что класс Manager расширяет Employee, сохраняя количество фондовых опционов, тогда как класс SalesPerson поддерживает хранение количества продаж. Добавьте новый файл класса (Manager.cs), в котором определен класс Manager со следующим автоматическим свойством:

// Менеджерам нужно знать количество их фондовых опционов.

class Manager : Employee

{

  public int StockOptions { get; set; }

}

Затем добавьте еще один новый файл класса (SalesPerson.cs), в котором определен класс SalesPerson с подходящим автоматическим свойством:

// Продавцам нужно знать количество продаж.

class SalesPerson : Employee

{

  public int SalesNumber { get; set; }

}

После того как отношение "является" установлено, классы SalesPerson и Manager автоматически наследуют все открытые члены базового класса Employee. В целях иллюстрации обновите операторы верхнего уровня, как показано ниже:

// Создание объекта подкласса и доступ к функциональности базового класса.

Console.WriteLine("***** The Employee Class Hierarchy *****\n");

SalesPerson fred = new SalesPerson

{

  Age = 31, Name = "Fred", SalesNumber = 50

};

<p id="AutBody_Root266">Вызов конструкторов базового класса с помощью ключевого слова base</p>

В текущий момент объекты классов SalesPerson и Manager могут создаваться только с использованием "бесплатно полученного" стандартного конструктора (см. главу 5). Памятуя о данном факте, предположим, что в класс Manager добавлен новый конструктор с шестью аргументами, который вызывается следующим образом:

...

// Предположим, что у Manager есть конструктор с такой сигнатурой:

// (string fullName, int age, int empId,

// float currPay, string ssn, int numbOfOpts)

Manager chucky = new Manager("Chucky", 50, 92, 100000, "333-23-2322", 9000);

Взглянув на список параметров, легко заметить, что большинство аргументов должно быть сохранено в переменных-членах, определенных в базовом классе Employee. Чтобы сделать это, в классе Manager можно было бы реализовать показанный ниже специальный конструктор:

public Manager(string fullName, int age, int empId,

               float currPay, string ssn, int numbOfOpts)

{

  // Это свойство определено в классе Manager.

  StockOptions = numbOfOpts;

  // Присвоить входные параметры, используя

  // унаследованные свойства родительского класса.

  Id = empId;

  Age = age;

  Name = fullName;

  Pay = currPay;

  PayType = EmployeePayTypeEnum.Salaried;

  // Если свойство SSN окажется доступным только для чтения,

  // тогда здесь возникнет ошибка на этапе компиляции!

  SocialSecurityNumber = ssn;

}

Первая проблема с таким подходом связана с тем, что если любое свойство определено как допускающее только чтение (например, свойство SocialSecurityNumber), то присвоить значение входного параметра string данному полю не удастся, как можно видеть в финальном операторе специального конструктора.

Перейти на страницу:

Похожие книги