Прежде чем определить класс Manager(), необходимо внести одно маленькое изменение в классе Employee:

public virtual decimal GetMonthlyPayment() {

 return salary/12;

}

что сделает метод GetMonthlyPayment() виртуальным (virtual). Это способ, которым C# сообщает, что данный метод в принципе может быть переопределен.

Можно подумать, что это означает изменение базового класса, что противоречит тезису о ненужности изменения базового класса. Однако добавление ключевого слова virtual на самом деле не является изменением, которое влечет за собой риск новых ошибок — при подходе VB необходимо было действительно переписать реализации нескольких методов. Кроме того, обычно при создании классов в C# заранее планируется, какие методы являются подходящими для переопределения. Если бы это был пример из реальной жизни, то метод GetMonthlyPayment() почти наверняка объявлялся бы виртуальным, поэтому на самом деле можно добавить класс Manager, не делая никаких изменений в классе Employee.

Класс Manager

Теперь можно определить класс Manager():

class Manager : Employee {

 private decimal bonus;

 public Manager(string name, decimal salary, decimal bonus) : base(name, salary) {

  this.bonus = bonus;

 }

 public Manager(string name, decimal salary) : this(name, salary, 100000M) {

 }

 public decimal Bonus {

  get {

   return bonus;

  }

 }

 public override string ToString() {

  return base.ToStrint() + ', bonus: ' + bonus;

 }

 public override decimal GetMonthlyPayment() {

  return base.GetMonthlyPayment() + bonus/12;

 }

}

Помимо почти завершенной реализации класса Employee, который был унаследован, Manager содержит следующие члены:

□ Поле bonus, которое будет использоваться для хранения бонуса менеджера, и соответствующее свойство.

□ Перезагруженный метод GetMonthlyPayment(), а также новую перегруженную версию метода ToString().

□ Два конструктора.

Поле bonus и соответствующее свойство Bonus не требуют дальнейших обсуждений. Однако мы внимательно рассмотрим переопределенные методы и новые конструкторы, так как они будут иллюстрировать важные свойства языка C#.

Переопределение метода

Переопределенная версия метода GetMonthlyPayment() является достаточно простой. Отметим, что она помечена ключевым словом override для сообщения компилятору, что мы переопределяем метод базового класса, как это делалось с методом Employee.ToString() :

public override decimal GetMonthlyPayment() {

 return base.GetMonthlyPayment() + bonus/12;

}

Переопределенная версия содержит также вызов версии этого метода из базового класса. При этом используется новое ключевое слово base, base действует таким же образом, как и this, за исключением того, что оно специально указывает, что надо использовать метод или свойство и т.д. из определения базового класса. При желании можно альтернативно реализовать переопределенную версию метода GetMonthlyPayment() следующим образом:

public override decimal GetMonthlyPayment() {

 return (Salary + bonus)/12;

}

но, чтобы показать использование ключевого слова base, был выбран другой вариант. В связи с этим есть одно действие, которое мы не смогли бы сделать:

public override decimal GetMonthlyPayment() {

 return (salary + bonus)/12; // неправильно

}

Код выглядит почти так же, как предыдущая версия, кроме того, что поле salary используется непосредственно, а не через свойство Salary. Можно предположить, что это более эффективное решение, поскольку фактически убирается вызов метода. Но компилятор будет инициировать ошибку, так как поле salary объявлялось как private (закрытое). Этот означает, что ничему вне класса Employee не разрешается видеть это поле. Даже производные классы не знают о закрытых полях базового класса.

Если необходимо, чтобы производные, но не связанные классы могли видеть поле, C# предоставит альтернативный уровень защиты protected (защищенный):

protected decimal salary; // можно сделать так

Если член класса объявлен как защищенный, то он виден только в этом классе и в производных классах. Однако обычно строго рекомендуется сохранять все поля закрытыми (private) по той же причине, по которой требуется сохранять переменные закрытыми в модулях классов VB. Дело в том, что при сокрытии реализации класса (или модуля класса) облегчается выполнение будущего обслуживания этого класса. Обычно модификатор protected используется для свойств и методов, которые предназначены только для того, чтобы разрешать производным классам получать доступ к свойствам определения базового класса.

Конструкторы класса Manager

Давайте добавим по крайней мере один конструктор для класса Manager в связи с

Добавить отзыв
ВСЕ ОТЗЫВЫ О КНИГЕ В ИЗБРАННОЕ

0

Вы можете отметить интересные вам фрагменты текста, которые будут доступны по уникальной ссылке в адресной строке браузера.

Отметить Добавить цитату