Россия, Москва, Московский государственный университет им. М. В. Ломоносова, 1989 |
Наследование во Flash MX
Можно ли здесь использовать альтернативное наследование?
То есть не копировать поля, а просто выстроить цепочку __proto__? Ответ на этот вопрос такой: можно, но осторожно. При использовании наследования с полным копированием мы вправе были не следить за тем, являются ли части нашего выражения обычными функциями или функциями-объектами. Если это функции-объекты, сами представляющие собой сложные выражения, то мы в какой-то момент можем одно из этих подвыражений изменить. Вот тут-то (если мы не использовали полное копирование) и выяснится, что на это подвыражение ссылается какой-нибудь еще объект. Впрочем, подобные проблемы можно решить, путем создания новых объектов (но только таких, которые действительно нужно создавать заново) в конструкторе. (Наш пример наследования функций не предоставляет возможности использовать конструктор, но добавить эту возможность несложно.) Итак, когда мы знаем, что проблем со множеством ссылок на изменяемые объекты у нас не будет, мы можем в функции newFunc вызов copyObj(f, somefunc); заменить на f.__proto__ = somefunc; после чего на выходе получим:
********** settingResFunction: resFuncPlus *********** ********** settingResFunction: resFuncDiv *********** ************* settingExpressions ************** ************* settingExpressions ************** ------------ function: particularFunc arguments = 1.5707963267949 newArgs = 1.5707963267949,[type Function],Derived class arg passed ------------ ------------ function: plusFunc arguments = 1.5707963267949,[type Function],Derived class arg passed newArgs = 1.5707963267949,[type Function],Derived class arg passed ------------ function: twoExprFunc arguments = 1.5707963267949,[type Function],Derived class arg passed Original object: = particularFunc :::::::::::::::::::: particularFunc(Math.PI/2) = 3 :::::::::::::::::::: ------------ function: anotherFunc arguments = -2 newArgs = -2,[type Function],Derived class arg passed ------------ ------------ function: divideFunc arguments = -2,[type Function],Derived class arg passed newArgs = -2,[type Function],Derived class arg passed ------------ function: twoExprFunc arguments = -2,[type Function],Derived class arg passed Original object: = anotherFunc :::::::::::::::::::: anotherFunc(-2) = -0.25 ::::::::::::::::::::
То есть все сработало правильно; видно также, что методы объектов-функций (такие, как setResFunction и setExpressionsFuncs ) не копировались при помощи newFunc и в результате не выводят про своем вызове отладочную информацию.
Полностью ли мы реализовали наследование функций?
Конечно, осталось еще довольно много работы. Нужно организовать хранение конструктора и его вызов при вызове newFunc (в нашем примере мы не пользовались конструкторами). Хорошо бы переписать наш пример с тем, чтобы функции-объекты (которые подвержены изменениям) создавать в конструкторе при помощи newFunc, тогда можно будет и разветвленные выражения с изменяемыми частями создавать при помощи rebel - наследования. Неплохо бы также реализовать механизм, аналогичный использованию ключевого слова super . Однако все подобные вещи мы уже проделывали в предыдущих параграфах этой лекции. Так что наведение глянца предоставляется читателю в качестве упражнения. А мы переходим к дальнейшим "фокусам".