Управление созданием базовых классов с помощью base
Управление созданием базовых классов с помощью base
В настоящий момент SalesPerson и Manager можно создать только с помощью конструктора, заданного по умолчанию. Поэтому предположим, что в тип Manager добавлен новый конструктор с шестью аргументами, который вызывается так, как показано ниже.
static void Main(string[] args) {
// Предположим, что есть следующий конструктор с параметрами
// (имя, возраст, ID, плата, SSN, число опционов).
Manager chucky = new Manager("Chucky", 35, 92, 100000, "333-23-2322", 9000);
}
Если взглянуть на список аргументов, можно сразу понять, что большинство из них должно запоминаться в членах-переменных, определенных базовым классом Employee. Для этого вы могли бы реализовать этот конструктор так, как предлагается ниже.
// Если не указано иное, конструктор подкласса автоматически вызывает
// конструктор базового класса, заданный по умолчанию.
public Manager(string fullName, int age, int empID, float currPay, string ssn, ulong numbOfOpts) {
// Это наш элемент данных.
numberOfOptions = numbOfOpts;
// Использование членов, наследуемых от Employee,
// для установки данных состояния.
ID = empID;
Age = age;
Name = fullName;
SocialSecurityNumber = ssn;
Pay = currPay;
}
Строго говоря, это допустимый, но не оптимальный вариант. В C#, если вы не укажете иное, конструктор базового класса, заданный по умолчанию, вызывается автоматически до выполнения логики любого пользовательского конструктора Manager. После этого текущая реализация получает доступ к множеству открытых свойств базового класса Employee, чтобы задать его состояние. Поэтому здесь при создании производного объекта вы на самом деле "убиваете семь зайцев" (пять наследуемых свойств и два вызова конструктора)!
Чтобы оптимизировать создание производного класса, вы должны реализовать свои конструкторы подклассов так, чтобы явно вызвался подходящий пользовательский конструктор базового класса, а не конструктор, заданный по умолчанию. Таким образом можно уменьшить число вызовов инициализации наследуемых членов (что экономит время). Позвольте для этого модифицировать пользовательский конструктор.
// На этот раз используем ключевое слово C# "base" для вызова
// пользовательского конструктора с базовым классом.
public Manager (string fullName, int age, int empID, float currPay, string ssn, ulong numbOfOpts): base(fullName, age, empID, currPay, ssn) {
numberOfOptions = numbOfOpts;
}
Здесь конструктор был дополнен довольно запутанными элементами синтаксиса. Непосредственно после закрывающей скобки списка аргументов конcтруктора стоит двоеточие, за которым следует ключевое слово C# base. В этой ситуации вы явно вызываете конструктор с пятью аргументами, определенный классом Employees избавляясь от ненужных вызовов в процессе создания дочернего класса.
Конструктор SalesPerson выглядит почти идентично.
// Как правило, каждый подкласс должен явно вызывать
// подходящий конструктор базового класса.
public SalesPerson(string fullName, int age, int empID, float currPay, string ssn, int numbOfSales): base(fullName, age, empID, currPay, ssn) {
numberOfSales = numbOfSales;
}
Вы должны также знать о том. что ключевое слово base можно использовать всегда, когда подклассу нужно обеспечить доступ к открытым или защищенным членам, определённым родительским классом. Использование этого ключевого слова не ограничено логикой конструктора. В нашем следующем обсуждении полиморфизма вы увидите примеры, в которых тоже используется ключевое слово base.