Vamos explicar de outra forma. Quando a variável é protected a única forma dessa variável ser usada em outra classe ,caso as classe estejam em pacotes diferentes, é através de herança . Certo? Então usando este exemplo de A e B . quais variáveis possui a classe A ? i apenas. e B? i tmb. A variável i da Classe B é herdada devido ao extends. Como podemos usar a variável i ?
nos construtores de B? sim
package p2;
import p1.*;
public class B extends p1.A{
public B (){
System.out.println(i);
}
public static void main(String[] args){
A a = new B();
B b = new B();
b.process(a);
System.out.println( a.getI());
}
}
Há outra forma de usar o field i ? sim , pela Classe B .
package p2;
import p1.*;
public class B extends p1.A{
B b ;
public B (){
b = new B();
System.out.println(b.i);
}
public static void main(String[] args){
A a = new B();
B b = new B();
b.process(a);
System.out.println( a.getI());
}
}
Certo ?
Agora a última parte . Eu poderia usar o campo i através da classe A , declarada dentro de B? não .
Eu poderia ter por exemplo:
package p2;
import p1.*;
public class B extends p1.A{
A a ;
public B (){
A = new A();
}
public static void main(String[] args){
A a = new B();
B b = new B();
b.process(a);
System.out.println( a.getI());
}
}
TUdo certo até aqui , só que quando tento usar o i dentro do construtor ou de qq outro método de instância ocorre o erro.
package p2;
import p1.*;
public class B extends p1.A{
A a ;
public B (){
A = new A();
System.out.println(a.i)//erro de compilação
}
public static void main(String[] args){
A a = new B();
B b = new B();
b.process(a);
System.out.println( a.getI());
}
}
O campo A declarado na classe B não é o herdeiro da classe A a relação é de composição , embora na classe haja a relação de herança. Mais isso é possível ? herança e composição ao mesmo tempo? sim . Então posso usar o campo i através de herança (lembre-se que é a única forma permitida para membros protected, já que o mesmo esta em outro pacote) , mas não posso usá-lo através do A ou seja da variável do tipo A. Veja como fica o final com as três possibilidades, que compilam ou não.
package p2;
import p1.*;
public class B extends p1.A{
A a ;
B b ;
public B (){
A = new A();
b = new B();
System.out.println(a.i)//erro de compilação
System.out.println(i)//ok
System.out.println(b.i)//ok
}
public static void main(String[] args){
A a = new B();
B b = new B();
b.process(a);
System.out.println( a.getI());
}
}
Se ficou complicado a explicação , esqueça herança e composição. E lembre apenas que membros protected só poderão ser usado , quando a classe estiver em outro pacote, por herança. Ou seja , usando o extends. Quem tá herdando a classe A ? A classe B então todas as variáveis do tipo B herdarão o campo i . Mas o A não é o A ? sim só que em outra classe que está em outro pacote ele só possui os atributos que estão visíveis que na realidade é somente o método public. A variável está invisível para ele mesmo.