Suponha que Shape
declara um draw()
método, seu Circle
subclasse substitui este método, Shape s = new Circle();
acabou de ser executado e a próxima linha especifica s.draw();
. Qual draw()
método é chamado: Shape
‘s draw()
método ou Circle
‘s draw()
método? O compilador não sabe qual draw()
método para chamar. Tudo o que ele pode fazer é verificar se um método existe na superclasse e verificar se a lista de argumentos da chamada do método e o tipo de retorno correspondem à declaração do método da superclasse. No entanto, o compilador também insere uma instrução no código compilado que, em tempo de execução, busca e usa qualquer referência que esteja em s
para chamar o correto draw()
método. Esta tarefa é conhecida como ligação tardia.
Criei um aplicativo que demonstra o polimorfismo de subtipo em termos de upcasting e ligação tardia. Este aplicativo consiste em Shape
, Circle
, Rectangle
e Shapes
classes, onde cada classe é armazenada em seu próprio arquivo de origem. A Listagem 1 apresenta as três primeiras classes.
Listagem 1. Declarando uma hierarquia de formas
class Shape
{
void draw()
{
}
}
class Circle extends Shape
{
private int x, y, r;
Circle(int x, int y, int r)
{
this.x = x;
this.y = y;
this.r = r;
}
// For brevity, I've omitted getX(), getY(), and getRadius() methods.
@Override
void draw()
{
System.out.println("Drawing circle (" + x + ", "+ y + ", " + r + ")");
}
}
class Rectangle extends Shape
{
private int x, y, w, h;
Rectangle(int x, int y, int w, int h)
{
this.x = x;
this.y = y;
this.w = w;
this.h = h;
}
// For brevity, I've omitted getX(), getY(), getWidth(), and getHeight()
// methods.
@Override
void draw()
{
System.out.println("Drawing rectangle (" + x + ", "+ y + ", " + w + "," +
h + ")");
}
}
A Listagem 2 apresenta o Shapes
classe de aplicação cuja main()
O método direciona o aplicativo.