Когда в подклассе определяется метод, имеющий то же самое имя, что и метод надкласса, подкласс переопределяет (overrides) этот метод. Ситуация, когда подкласс порождается от существующего класса, встречается достаточно часто. Например, в любой момент можно определить метод toString() класса и тем са_ мым переопределить метод toString() класса Object.
Зачастую переопределение методов производится не с целью полной замены, а лишь для того, чтобы расширить их функциональность. Для этого метод должен иметь возможность вызывать переопределенный метод. В определенном смысле такой прием по аналогии с конструкторами можно назвать вызовом методов по цепочке. Однако вызвать переопределенный метод гораздо менее удобно, чем кон_ структор надкласса.
Рассмотрим следующий пример. Предположим, что класс Rectangle определяет метод toString() (что должно быть сделано чуть ли не в первую очередь) следую_ щим образом:
Если уж вы реализовали метод toString() в классе Rectangle, то тем более его не_ обходимо переопределить в классе PositionedRectangle, чтобы экземпляры под_ класса могли иметь строковое представление, отражающее значения не только ширины и высоты, но и всех остальных их свойств. PositionedRectangle – очень простой класс и для него достаточно, чтобы метод toString() просто возвращал значения всех его свойств. Однако ради примера будем обрабатывать значения свойств координат в самом классе, а обработку свойств width и height делегируем надклассу. Сделать это можно примерно следующим образом:
return "(" + this.x + "," + this.y + ") " + // поля этого класса Rectangle.prototype.toString.apply(this); // вызов надкласса по цепочке
}
Реализация метода toString() надкласса доступна как свойство объекта_прото_ типа надкласса. Обратите внимание: мы не можем вызвать метод напрямую – нам пришлось воспользоваться методом apply(), чтобы указать, для какого объ_ екта вызывается метод.
Однако если в PositionedRectangle.prototype добавить свойство superclass, можно сделать так, чтобы этот код не зависел от типа надкласса:
return "(" + this.x + "," + this.y + ") " + // поля этого класса this.superclass.prototype.toString.apply(this);
}
Еще раз обратите внимание, что свойство superclass может использоваться в ие_ рархии наследования только один раз. Если оно будет задействовано классом и его подклассом, это приведет к бесконечной рекурсии.