Прежде всего напомним один очень важный принцип: переменная ссылки на суперкласс может ссылаться на объект подкласса. В Java этот принцип используется для вызова переопределяемых методов во время выполнения. Если переопределяемый метод вызывается по ссылке на суперкласс, то исполняющая система Java определяет по типу объекта, какой именно вариант метода следует вызвать, причем делает это во время выполнения программы. Если ссылки указывают на разные типы объектов, то и вызываться будут разные версии переопределенных методов. Иными словами, вариант переопределенного метода для вызова определяет не тип переменной, а тип объекта, на который она ссылается. Так, если суперкласс содержит метод, переопределяемый в подклассе, то вызывается метод, соответствующий тому типу объекта, на который указывает переменная ссылки на суперкласс.
Ниже приведен простой пример, демонстрирующий динамическую диспетчеризацию методов в действии. // Демонстрация динамической диспетчеризации методов. class Sup { void who { System.out.println("who in Sup"); } } class Subl extends Sup { void who { System.out.println("who in Subl"); } } class Sub2 extends Sup { void who { System.out.println("who in Sub2"); } } class DynDispDemo { public static void main(String args[]) { Sup superOb = new Sup; Subl subObl = new Subl; Sub2 sub0b2 = new Sub2; Sup supRef; // В каждом из приведенных ниже вызовов конкретный вариант // метода who выбирается во время выполнения по типу // объекта, на который делается ссылка. supRef = superOb; supRef.who; supRef = subObl; supRef.who; supRef = sub0b2; supRef.who; } }
Результат выполнения данной программы выглядит следующим образом: who in Sup who in Subl who in Sub2
В данном примере программы определяются суперкласс Sup и два его подкласса Subl и Sub2. В классе Sup объявляется метод who , переопределяемый в его подклассах. В методе main создаются объекты типа Sup, Subl и Sub2. Там же объявляется переменная supRef ссылки на объект типа Sup. Затем переменной supRef в методе main поочередно присваиваются ссылки на объекты разного типа, и далее эти ссылки используются для вызова метода who . Как следует из результата выполнения данной программы, вызываемый вариант метода who определяется типом объекта, на который ссылается переменная supRef в момент вызова, а не типом самой этой переменной. Причины для переопределения методов
Как упоминалось выше, переопределяемые методы обеспечивают соблюдение принципа полиморфизма при выполнении программ на Java. Полиморфизм в объектно-ориентированных программах имеет большое значение потому, что благодаря ему появляется возможность объявить в суперклассе методы, общие для всех его подклассов, а в самих подклассах — определить специфические реализации всех этих методов или некоторых из них. Переопределение методов — один из способов, которыми в Java реализуется принцип полиморфизма “один интерфейс — множество методов”.