(→Cenário A) |
(→Cenário B) |
||
Line 41: | Line 41: | ||
No cenário A, o atributo é declarado, mas já tem um iniciador por omissão explÃcito. Por isso, já não é possÃvel definir no construtor o seu valor. | No cenário A, o atributo é declarado, mas já tem um iniciador por omissão explÃcito. Por isso, já não é possÃvel definir no construtor o seu valor. | ||
− | + | <java5> | |
public class SuperClasse { | public class SuperClasse { | ||
private int _a = 78; | private int _a = 78; | ||
Line 63: | Line 63: | ||
} | } | ||
+ | </java5> | ||
== Classe <code>SubClasse</code> == | == Classe <code>SubClasse</code> == |
O exemplo aqui apresentado ilustra o processo de especialização de uma classe por outra, de si derivada. Além do processo de especialização, o exemplo permite ver ainda aspectos como a iniciação de atributos final e a invocação explÃcita de construtores de superclasses (i.e., a sequência de iniciação de um objecto de uma classe derivada de outra).
A aplicação exemplo ilustra ainda o processo de upcasting, i.e., utilizar uma referência de um tipo mais geral que o do objecto que refere.
SuperClasse
A classe SuperClasse
representa o conceito mais geral, que irá ser posteriormente especializado.
São apresentados dois cenários para ilustrar o comportamento na iniciação de um atributo declarado final.
No cenário A, o atributo é declarado, mas não tem um iniciador por omissão explÃcito. Por isso, é possÃvel definir no construtor o seu valor.
<java5>
public class SuperClasse { private int _a = 78; protected final int _x; // cenário A SuperClasse(int x) { System.out.println("-- calling SuperClasse.SuperClasse(" + x + ")"); _a = (int)(100*Math.random()); _x = x; // ok: cenário A } final int getA() { System.out.println("-- calling SuperClasse.getA() returns " + _a); return _a; } protected int getX() { System.out.println("-- calling SuperClasse.getX() returns " + _x); return _x; } }
</java5>
No cenário A, o atributo é declarado, mas já tem um iniciador por omissão explÃcito. Por isso, já não é possÃvel definir no construtor o seu valor. <java5>
public class SuperClasse { private int _a = 78; protected final int _x = 93; // iniciação SuperClasse(int x) { System.out.println("-- calling SuperClasse.SuperClasse(" + x + ")"); _a = (int)(100*Math.random()); //_x = x; // erro: já está iniciada } final int getA() { System.out.println("-- calling SuperClasse.getA() returns " + _a); return _a; } protected int getX() { System.out.println("-- calling SuperClasse.getX() returns " + _x); return _x; } }
</java5>
SubClasse
A classe SuibClasse corresponde a uma especialização da superclasse e redefine o método getX.
Note-se a sintaxe de invocação do construtor da superclasse, utilizando a palavra chave super: esta chamada é necessária, pois a não existência de um construtor sem argumentos na superclasse faz com que o comportamento por omissão do construtor da subclasse (na iniciação da porção do objecto correspondente à superclasse) não possa ser executado.
public class SubClasse extends SuperClasse { SubClasse() { super(4); System.out.println("-- calling SubClasse.SubClasse()"); } protected int getX() { int result = 1 + super.getX(); System.out.println("-- calling SubClasse.getX() returns " + result); return result; } }
Note-se o processo de upcasting (em myD
): a referência é para SuperClasse
e o objecto é do tipo SubClasse
.
Aplicação
Note-se que a chamada a getA
(final) é sempre executada fazendo do uso do código da superclasse (o facto de o método ser final
impede a redefinição pelas subclasses).
public class Aplicação { public static void main(String args[]) { SuperClasse myS = new SuperClasse(8); // ok: mesmo tipo SuperClasse myD = new SubClasse(); // ok: upcasting System.out.println("in main: myS.getA() = " + myS.getA()); System.out.println("in main: myS.getX() = " + myS.getX()); System.out.println("in main: myD.getA() = " + myD.getA()); System.out.println("in main: myD.getX() = " + myD.getX()); } }
$ java Aplicação -- calling SuperClasse.SuperClasse(8) -- calling SuperClasse.SuperClasse(4) -- calling SubClasse.SubClasse() -- calling SuperClasse.getA() returns 46 in main: myS.getA() = 46 -- calling SuperClasse.getX() returns 8 in main: myS.getX() = 8 -- calling SuperClasse.getA() returns 9 in main: myD.getA() = 9 -- calling SuperClasse.getX() returns 4 -- calling SubClasse.getX() returns 5 in main: myD.getX() = 5