Когда подкласс желает изменить реализацию деталей виртуального метода, он прибегает к помощи ключевого слова override. Например, классы SalesPerson и Manager могли бы переопределять метод GiveBonus(), как показано ниже (предположим, что класс PtSalesPerson не будет переопределять GiveBonus(), а потому просто наследует его версию из SalesPerson):
using System;
class SalesPerson : Employee
{
...
// Бонус продавца зависит от количества продаж.
public override void GiveBonus(float amount)
{
int salesBonus = 0;
if (SalesNumber >= 0 && SalesNumber <= 100)
salesBonus = 10;
else
{
if (SalesNumber >= 101 && SalesNumber <= 200)
salesBonus = 15;
else
salesBonus = 20;
}
base.GiveBonus(amount * salesBonus);
}
}
class Manager : Employee
{
...
public override void GiveBonus(float amount)
{
base.GiveBonus(amount);
Random r = new Random();
StockOptions += r.Next(500);
}
}
Обратите внимание, что каждый переопределенный метод может задействовать стандартное поведение посредством ключевого слова base.
Таким образом, полностью повторять реализацию логики метода GiveBonus() вовсе не обязательно, а взамен можно повторно использовать (и расширять) стандартное поведение родительского класса.
Также предположим, что текущий метод DisplayStats() класса Employee объявлен виртуальным:
public virtual void DisplayStats()
{
Console.WriteLine("Name: {0}", Name);
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