Материал предоставлен https://it.rfei.ru

Полиморфизм и динамический поиск метода

На какой объект будет реально указывать ссылка во время выполнения, не всегда можно точно определить на этапе компиляции. Полиморфизм позволяет ссылке указывать на объекты разных типов в разное время во время выполнения. Ссылка супертипа демонстрирует полиморфное поведение, поскольку она может указывать на объекты своих подтипов.

Когда у объекта вызывается He-private-метод экземпляра, то реально выполняемое описание метода определяется одновременно и типом объекта во время выполнения, и сигнатурой метода. Динамический поиск метода — это основанный на типе объекта процесс определения того, какое описание метода обозначается данной сигнатурой метода во время выполнения. Однако вызов private-метода экземпляра не является полиморфным, поскольку вызов может произойти только внутри класса и ограничивается реализацией private-метода во время компиляции.

Иерархия наследования, изображенная на рис. 6.5, реализована в примере 6.14. Реализация метода draw() переопределена во всех подклассах класса Shape. Вызов метода draw() в двух циклах в строках (3) и (4) в примере 6.14 основывается на полиморфном поведении ссылок и динамическом поиске метода. В массиве shapes содержатся ссылки типа Shape (Фигура), обозначающие Circle (Окружность), Rectangle (Прямоугольник) и Square (Квадрат), как показано в строке (1). Во время выполнения динамический поиск находит реализацию метода draw(), которую надо выполнить на основании типа объектов, на которые указывают элементы массива. Такая же схема применяется и для случая с массивом drawables в строке (2), который содержит ссылки типа IDrawable, а им можно присвоить любой объект класса, который реализует интерфейс IDrawable. Первый цикл будет продолжать работать без изменений, если объекты нового подкласса класса Shape добавить в массив shapes. Если они не переопределяют метод draw(), будет выполнена унаследованная версия метода. Такое полиморфное поведение применимо к массиву drawables, в котором объекты подтипа с гарантией реализуют интерфейс IDrawable.

Полиморфизм и динамический поиск метода образуют мощную парадигму программирования, которая упрощает определения клиентов, содействует разделению объектов и поддерживает динамическую перенастройку связей между объектами во время выполнения.

Рис. 6.5. Полиморфные методы

Пример 6.14. Полиморфизм и динамический поиск метода

interface IDrawable {
    void draw();
}

class Shape implements IDrawable {
    public void draw() { System.out.println("Drawing a Shape."); }
}

class Circle extends Shape {
    public void draw() { System.out.println("Drawing a Circle."); }
}

class Rectangle extends Shape {
    public void draw() { System.out.println("Drawing a Rectangle."); }
}

class Square extends Rectangle {
    public void draw() { System.out.println("Drawing a Square."); }
}

class Map implements IDrawable {
    public void draw() { System.out.println("Drawing a Map."); }
}

public class PolymorphRefs {
    public static void main(String[] args) {
        Shape[] shapes = { new Circle(), new Rectangle(), new Square() };   // (1)
        IDrawable[] drawables = { new Shape(), new Rectangle(), new Map() };// (2)

        System.out.println("Draw shapes:");
        for (int i = 0; i < shapes.length; i++)                           // (3)
            shapes[i].draw();

        System.out.println("Draw drawables:");
        for (int i = 0; i < drawables.length; i++)                        // (4)
            drawables[i].draw();
    }
}

Вывод программы:

Draw shapes:
Drawing a Circle.
Drawing a Rectangle.
Drawing a Square.
Draw drawables:
Drawing a Shape.
Drawing a Rectangle.
Drawing a Map.
Преобразование типов значений ссылокНаследование в сравнении с агрегацией