Руководство по actionscript. часть 1, стр. 115
Полиморфизм не только упрощает взаимодействие между программистами, но и позволяет применять и расширять библиотеки, не требуя при этом доступа к их исходному коду. Некоторые разработчики утверждают, что полиморфизм — это величайший вклад объектно-ориентированного программирования в компьютерную науку.
Наследование в сравнении с композицией
Композиция, представляющая альтернативный вид отношений между объектами, зачастую соперничает с наследованием в качестве методики объектно-ориентиро-
ванного дизайна. В композиции один класс (внешний) хранит экземпляр другого класса (внутреннего) в переменной экземпляра. Внешний класс поручает работу внутреннему классу, вызывая методы над этим экземпляром. Вот базовый подход, представленный обобщенным кодом:
// Внутренний класс является аналогом суперкласса в наследовании public class BackEnd {
public function doSomething ( ) {
}
}
// Внешний класс является аналогом подкласса в наследовании public class FrontEnd {
// Экземпляр внутреннего класса сохраняется в закрытой переменной
// экземпляра, в данном случае в закрытой пременной be
private var be;
// Конструктор создает экземпляр внутреннего класса public function FrontEnd ( ) { be = new BackEnd( );
}
// Этот метод поручает работу методу doSomething( ) класса BackEnd public function doSomething ( ) { be. doSomething( );
}
}
Обратите внимание, что класс FrontEnd не расширяет класс BackEnd. Композиция не требует использования собственного особого синтаксиса, как это происходит с наследованием. Более того, внешний класс может использовать подмножество методов внутреннего класса, все методы или добавлять собственные несвязанные методы. Имена методов во внешнем классе могут полностью совпадать с именами методов во внутреннем классе или совершенно отличаться. Внешний класс может ограничивать, расширять или переопределять возможности внутреннего класса, играя такую же роль, как подкласс в наследовании.
Ранее в этой главе было описано, как с помощью наследования класс Square может ограничивать поведение класса Rectangle. В листинге 6.2 показано, как одно и то же отношение между классами может быть реализовано с использованием композиции вместо наследования. В предлагаемом коде класс Rectangle остался неизмененным. Однако на этот раз класс Square не расширяет Rectangle. Вместо этого в классе Square описана переменная г, содержащая экземпляр класса Rectangle. Фильтрация всех операций над экземпляром, хранящимся в переменной г, происходит через public-методы класса Square. Класс Square переадресует, или делегирует, вызовы методов экземпляру, хранящемуся в переменной г. Обратите внимание, что, поскольку метод setSize ( ) класса Square не перекрывает метод setSize ( ) класса Rectangle, сигнатура метода setSize ( ) класса Square не обязана совпадать с сигнатурой метода setSize ( ) класса Rectangle. В методе setSize ( ) класса Square можно определить один-единственный параметр, в отличие от метода setSize ( ) класса Rectangle, в котором определено два параметра.