Console.WriteLine("Id: {0}", Id);
Console.WriteLine("Age: {0}", Age);
Console.WriteLine("Pay: {0}", Pay);
Console.WriteLine("SSN: {0}", SocialSecurityNumber);
}
Тогда каждый подкласс может переопределять метод DisplayStats
DisplayStats из класса Manager (класс SalesPerson реализовывал бы метод DisplayStats в похожей манере, выводя на консоль количество продаж):// Manager.cs
public override void DisplayStats
{
base.DisplayStats;
// Вывод количества фондовых опционов
Console.WriteLine("Number of Stock Options: {0}", StockOptions);
}
// SalesPerson.cs
public override void DisplayStats
{
base.DisplayStats;
// Вывод количества продаж
Console.WriteLine("Number of Sales: {0}", SalesNumber);
}
Теперь, когда каждый подкласс может истолковывать эти виртуальные методы значащим для него образом, их экземпляры ведут себя как более независимые сущности:
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;
Вот результат тестового запуска приложения в его текущем виде:
***** The Employee Class Hierarchy *****
Name: Chucky
ID: 92
Age: 50
Pay: 100300
SSN: 333-23-2322
Number of Stock Options: 9337
Name: Fran
ID: 93
Age: 43
Pay: 5000
SSN: 932-32-3232
Number of Sales: 31
Переопределение виртуальных членов с помощью Visual Studio/Visual Studio Code
Вы наверняка заметили, что при переопределении члена класса приходится вспоминать тип каждого параметра, не говоря уже об имени метода и соглашениях по передаче параметров (ref
out и params). В Visual Studio и Visual Studio Code доступно полезное средство IntelliSense, к которому можно обращаться при переопределении виртуального члена. Если вы наберете слово override внутри области действия типа класса (и затем нажмете клавишу пробела), то IntelliSense автоматически отобразит список всех допускающих переопределение членов родительского класса, исключая уже переопределенные методы.Если вы выберете член и нажмете клавишу <Enter
>, то IDE-среда отреагирует автоматическим заполнением заглушки метода. Обратите внимание, что вы также получаете оператор кода, который вызывает родительскую версию виртуального члена (можете удалить эту строку, если она не нужна). Например, при использовании описанного приема для переопределения методаDisplayStats вы обнаружите следующий автоматически сгенерированный код:public override void DisplayStats
{
base.DisplayStats;
}
Запечатывание виртуальных членов
Вспомните, что к типу класса можно применить ключевое слово sealed
PtSalesPerson был запечатан на основе предположения о том, что разработчикам не имеет смысла дальше расширять эту линию наследования.Следует отметить, что временами желательно не запечатывать класс целиком, а просто предотвратить переопределение некоторых виртуальных методов в производных типах. В качестве примера предположим, что вы не хотите, чтобы продавцы с частичной занятостью получали специальные бонусы. Предотвратить переопределение виртуального метода GiveBonus
PtSalesPerson можно, запечатав данный метод в классе SalesPerson:// Класс SalesPerson запечатал метод GiveBonus!
class SalesPerson : Employee
{
...
Бьёрн Страуструп , Ирина Сергеевна Козлова , Бьерн Страуструп , Валерий Федорович Альмухаметов
Программирование, программы, базы данных / Базы данных / Программирование / Учебная и научная литература / Образование и наука / Книги по IT