Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Лекция 2. Наследование.doc
Скачиваний:
5
Добавлен:
15.11.2019
Размер:
273.92 Кб
Скачать

Поддержка полиморфизма в с#

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

// В классе Employee определен новый метод для поощрения сотрудников

public class Employee

{

public void GiveBonus(float amount)

{

currPay += amount;

}

. . . .

}

Поскольку этот метод определен в базовом классе как publiс, вы теперь можете поощрять продавцов и менеджеров:

// Поощрения объектам производных классов

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

Chucky.GiveBonus(300);

Chucky.DisplayStats( );

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

Fran.GiveBonus(200);

Fran.DisplayStats( );

.

Проблема заключается в том, что унаследованный метод GiveBonus( ) пока работает абсолютно одинаково в отношении объектов обоих производных клас-— и объектов Salesperson, и объектов Manager. Однако, конечно, было бы лучше, чтобы для объекта каждого класса использовался свой уникальный вариант метода. Например, при поощрении продавцов можно учитывать их объем продаж. Менеджерам помимо денежного поощрения можно выдавать дополнительные опционы на акции. Поэтому задачу можно сформулировать так: «Как заставить один и тот же метод по-разному реагировать на объекты разных классов?»

Для решения этой задачи в С# предусмотрено понятие полиморфизма. Полиморфизм позволяет переопределять реакцию объекта производного класса на метод, определенный в базовом классе. Для реализации полиморфизма в нашем приложении мы воспользуемся ключевыми словами С#: virtual и override. Если базовый класс определяет метод, который должен быть замещен в производном классе, этот метод должен быть объявлен как виртуальный (конечно, при помощи ключевого слова virtual):

public class Employee

{

// Для метода GiveBonus( ) предусмотрена реализация по умолчанию.

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

public virtual void GiveBonus(float amount)

{

currPay += amount;

}

. . . .

}

Если вы хотите переопределить виртуальный метод, необходимо заново определить метод в производном классе, использовав ключевое слово override:

public class Salesperson : Employee

{

// На размер поощрения продавцу будет влиять объем его продаж

public override void GiveBonus(float amount)

{

int salesBonus = 0;

if(numberOfSales >= 0 && numberOfSales <=100)

salesBonus = 10;

else if(numberOfSales >= 101 && numberOfSales <= 200)

salesBonus = 15;

else

salesBonus = 20; // Для объема продаж больше 200

base.GiveBonus(amount * salesBonus);

}

. . . .

}

public class Manager Employee

{

private Random r = new Random( );

// Помимо денег менеджеры также получают некоторое количество опционов

// на акции

public override void GiveBonus(float amount)

{

// Деньги: увеличиваем зарплату

base.GiveBonus(amount);

// Опционы на акции: увеличиваем их количество

numberOfOptions += (ulong)r.Next(500);

}

. . . .

}

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

Метод Employee.DisplayStats( ) у нас также определен как virtual, и он замещен в производных классах таким образом, чтобы показывать текущий объем продаж, если речь идет о продавце, или количество опционов,-имеющееся в настоящее время в распоряжении менеджера. Теперь, когда для каждого из производных классов определены собственные варианты этих двух методов, объекты разных классов ведут себя по-разному:

// Улучшенная система поощрений!

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

chucky.GiveBonus(300);

chucky.DisplayStats( );

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

fran.GiveBonus(200);

fran.DisplayStats( );

Мы с вами научились использовать полиморфизм для переопределения поведения производных классов. Однако, как, наверное, вы догадываетесь, возможности полиморфизма этим далеко не исчерпываются.