Философия Java


Выработка правильного поведения - часть 2


class Triangle extends Shape { void draw() { System.out.println("Triangle.draw()"); } void erase() { System.out.println("Triangle.erase()"); } }

public class Shapes { public static Shape randShape() { switch((int)(Math.random() * 3)) { default: case 0: return new Circle(); case 1: return new Square(); case 2: return new Triangle(); } } public static void main(String[] args) { Shape[] s = new Shape[9]; // Заполним массив шейпами:

for(int i = 0; i < s.length; i++) s[i] = randShape(); // Сделаем вызов полиморфного метода:

for(int i = 0; i < s.length; i++) s[i].draw(); } } ///:~

Базовый класс Shape предоставляет общий интерфейс для всех наследников от Shape, это означает, что все шейпы могут быть нарисованы и стерты. Дочерние классы перекрывают эти определения для обеспечения уникального поведения в зависимости от типа шейпа.

Главный класс Shapes содержит static метод - randShape( ), который возвращает ссылку на случайно выбранный объект Shape каждый раз, когда Вы вызываете его. Заметьте, что приведение к базовому типу происходит каждый раз при return-е, который ссылается на Circle, Square или Triangle и посылает их из метода, как возвращаемый параметр. Так что, когда Вы вызываете этот метод Вы не можете узнать, какого типа возвращается параметр, поскольку всегда возвращается базовый тип Shape.

main( ) содержит массив из ссылок Shape заполненный вызовами randShape( ). На этом этапе Вы знаете, что Вы имеете некоторое множество ссылок на объекты типа Shape, но Вы не знаете ничего о них больше (и не больше, чем знает компилятор). В любом случае, когда Вы перемещаетесь по этому массиву и вызываете draw( ) для каждого элемента, то автоматически проставляется правильный тип, как Вы можете посмотреть это на примере:

Circle.draw() Triangle.draw() Circle.draw() Circle.draw() Circle.draw() Square.draw() Triangle.draw() Square.draw() Square.draw()

Естественно, поскольку шейпы вызываются случайным образом, то и результаты вывода могут быть различны. Причина вызова шейпов случайным образом обусловлена тем, что бы была возможность показать, что компилятор не имеет специальных знаний, для создания правильных вариантов при компиляции. Все вызовы draw( ) сделаны посредством динамической связи.




Начало  Назад  Вперед