Модель наследования «включение-делегирование»
В лабораторной работе №9 была рассмотрена модель классического наследования («быть» – is-a). Вторая разновидность – модель включения-делегирования («иметь» – has-a). Рассмотрим нас два независимых класса: автомобиль и двигатель:
public class Motor {...}public class Car {...}Понятно, что эти два класса должны взаимодействовать друг с другом и эти отношения должны быть зафиксированы. Классическое наследование здесь неприменимо, поскольку трудно производить машину от двигателя или двигатель от машины. Здесь более уместен вариант отношения включения-делегирования: пусть машина включает в себя двигатель и передает этому классу необходимые команды. В терминологии ООП контейнерный класс (в нашем случае Car) называется родительским (parent), а внутренний класс, который помещен внутрь контейнерного, называется дочерним (child).
Помещение радиоприемника внутрь автомобиля влечет за собой внесение в определение класса Саr следующих изменений:
// Автомобиль «имеет» (has-a) двигательpublic class Саr{ // Внутренний двигатель private Motor m;}Важно, что внутренний класс Motor был объявлен как рrivate. С точки зрения инкапсуляции все верно. Однако при этом неизбежно возникает проблема запуска двигателя. Переводя на язык ООП – задача внешнего взаимодействия с внутренним классом? Ответственность за создание объекта внутреннего класса несет внешний контейнерный класс. В нем код для создания объектов внутреннего класса можно помещать куда угодно, но обычно он помещается среди конструкторов контейнерного класса:
public class Car{ public Car() {... m = new Motor(); }}Таким образом, двигатель внутри автомобиля создается вместе с автомобилем. Однако, вопрос о том, как именно можно завести автомобиль, остался нерешенным. Ответ на него выглядит так: для того что бы воспользоваться возможностями внутреннего класса, необходимо делегирование. Делегирование заключается в простом добавлении во внешний контейнерный класс методов для обращения ко внутреннему классу:
public class Car{ public void TheMotor(bool state) { // Передаем (делегируем) запрос внутреннему объекту m.TurnOn(state); }}Итоговый код:
public class Motor { bool ON; public void OnOff(bool state) { ON = state; if (ON) Console.WriteLine("Двигатель запущен."); else Console.WriteLine("Двигатель заглушен."); }}public class Car { private Motor m; public Car() { m = new Motor(); } public void TheMotor(bool state) { // Передаем (делегируем) запрос внутреннему объекту m.OnOff(state); } } class Program{ static void Main(string[] args) { Car a = new Car(); a.TheMotor(true); Console.ReadKey(); }}Результат:
Двигатель запущен.
Дата добавления: 2021-12-14; просмотров: 432;