Чтение онлайн

ЖАНРЫ

Язык программирования C#9 и платформа .NET5
Шрифт:

// Ошибка на этапе компиляции! Доступ к закрытому вложенному

// классу невозможен!

OuterClass.PrivateInnerClass inner2;

inner2 = new OuterClass.PrivateInnerClass;

Для применения такой концепции в примере с сотрудниками предположим, что определение

BenefitPackage
теперь вложено непосредственно в класс
Employee
:

partial class Employee

{

public class BenefitPackage

{

//
Предположим, что есть другие члены, представляющие

// медицинские/стоматологические программы и т.д.

public double ComputePayDeduction

{

return 125.0;

}

}

...

}

Процесс вложения может распространяться настолько "глубоко", насколько требуется. Например, пусть необходимо создать перечисление по имени

BenefitPackageLevel
, документирующее разнообразные уровни льгот, которые может выбирать сотрудник. Чтобы программно обеспечить тесную связь между типами
Employee
,
BenefitPackage
и
BenefitPackageLevel
, перечисление можно вложить следующим образом:

// В класс Employee вложен класс BenefitPackage.

public partial class Employee

{

// В класс BenefitPackage вложено перечисление BenefitPackageLevel.

public class BenefitPackage

{

public enum BenefitPackageLevel

{

Standard, Gold, Platinum

}

public double ComputePayDeduction

{

return 125.0;

}

}

...

}

Вот как приходится использовать перечисление

BenefitPackageLevel
из-за отношений вложения:

...

// Определить уровень льгот.

Employee.BenefitPackage.BenefitPackageLevel myBenefitLevel =

Employee.BenefitPackage.BenefitPackageLevel.Platinum;

Итак, к настоящему моменту вы ознакомились с несколькими ключевыми словами (и концепциями), которые позволяют строить иерархии типов, связанных посредством классического наследования, включения и вложения. Не беспокойтесь, если пока еще не все детали ясны. На протяжении оставшихся глав книги будет построено немало иерархий. А теперь давайте перейдем к исследованию последнего принципа ООП — полиморфизма.

Третий принцип объектно-ориентированного программирования: поддержка полиморфизма в C#

Вспомните, что в базовом классе

Employee
определен метод по имени
GiveBonus
, который первоначально был реализован так (до его обновления с целью использования шаблона свойств):

public partial class Employee

{

public void GiveBonus(float amount) => _currPay += amount;

...

}

Поскольку

метод
GiveBonus
был определен с ключевым словом
public
, бонусы можно раздавать продавцам и менеджерам (а также продавцам с частичной занятостью):

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

// Выдать каждому сотруднику бонус?

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

chucky.GiveBonus(300);

chucky.DisplayStats;

Console.WriteLine;

SalesPerson fran = new SalesPerson("Fran", 43, 93, 3000, "932-32-3232", 31);

fran.GiveBonus(200);

fran.DisplayStats;

Console.ReadLine;

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

GiveBonus
функционирует идентично для всех подклассов. В идеале при подсчете бонуса для штатного продавца и частично занятого продавца должно приниматься во внимание количество продаж. Возможно, менеджеры вместе с денежным вознаграждением должны получать дополнительные фондовые опционы. Учитывая это, вы однажды столкнетесь с интересным вопросом: "Как сделать так, чтобы связанные типы реагировали по-разному на один и тот же запрос?". Попробуем найти на него ответ.

Использование ключевых слов virtual и override

Полиморфизм предоставляет подклассу способ определения собственной версии метода, определенного в его базовом классе, с применением процесса, который называется переопределением метода. Чтобы модернизировать текущее проектное решение, необходимо понимать смысл ключевых слов

virtual
и
override
. Если базовый класс желает определить метод, который может быть (но не обязательно) переопределен в подклассе, то он должен пометить его ключевым словом
virtual
:

partial class Employee

{

// Теперь этот метод может быть переопределен в производном классе.

public virtual void GiveBonus(float amount)

{

Pay += amount;

}

...

}

На заметку! Методы, помеченные ключевым словом

virtual
, называются виртуальными методами.

Когда подкласс желает изменить реализацию деталей виртуального метода, он прибегает к помощи ключевого слова

override
. Например, классы
SalesPerson
и
Manager
могли бы переопределять метод
GiveBonus
, как показано ниже (предположим, что класс
PtSalesPerson
не будет переопределять
GiveBonus
, а потому просто наследует его версию из
SalesPerson
):

using System;

Поделиться с друзьями: