Midificador protected (Dúdidas)

Lendo sobre os modificadores de acesso, me surgiu uma grande dúvida, veja só oque diz a Wikipédia sobre o modificador protected:

[quote]Modificador de acesso protected
A instrução protected indica que o método ou a variável assim declarada possa ser acessada somente dentro do pacote em que está contida através de uma subclasse. [/quote]

Então fui realizar alguns testes e gostaria de saber por que isso funciona se as classes estão em pacotes diferentes ?

Segue a classe usada com base com um atributo int protected

package teste2;

public class Super 
{	
	protected int i = 1;
}

Primeiro exemplo: uma subclasse de Super só que em pacote direferente, tem acesso ao atributo protected

package teste3;

import teste2.Super;

public class Sub extends Super 
{	
	int i2 = i;
	
	public static void main(String[] args) 
	{
		System.out.println(new Sub().i2);
	}	
}

Segundo exemplo: uma outra classe que não é subclasse de Super e mesmo assim tem acesso ao atributo protected

package teste2;

public class OtherClass 
{	
	int i = new Super().i;
	
	public static void main(String[] args) 
	{
		System.out.println(new OtherClass().i);
	}
}

Se alguém ai puder me explicar isso, por favor, obrigado…

Seus modificadores de acesso estão como public. Portanto podem ser acessados por qualquer classe contida em qualquer pacote.

Em relação ao modificador protected, membros com este modificador só podem ser acessados por membros do mesmo pacote, porém, membros de outros pacotes acessam também desde que seja por herança.

[quote=lincolnti]Seus modificadores de acesso estão como public. Portanto podem ser acessados por qualquer classe contida em qualquer pacote.

Em relação ao modificador protected, membros com este modificador só podem ser acessados por membros do mesmo pacote, porém, membros de outros pacotes acessam também desde que seja por herança.[/quote]

E como no exemplo dois a classe que não é subclasse de Super consegue acessar o atributo ?

Porque ambos estão no mesmo pacote.

basta ver a seguinte linha das duas classes:

package teste2;

[quote=lincolnti]Porque ambos estão no mesmo pacote.

basta ver a seguinte linha das duas classes:

package teste2;

Isso quer dizer então que o modificador protected é mais abrangente que o modificador package (default) ?

[quote=espiaoweb2011]

Isso quer dizer então que o modificador protected é mais abrangente que o modificador package (default) ?[/quote]

Sim, porque membros default somente podem ser acessado por membros do mesmo pacote.

[quote=lincolnti][quote=espiaoweb2011]

Isso quer dizer então que o modificador protected é mais abrangente que o modificador package (default) ?[/quote]

Sim, porque membros default somente podem ser acessador por membros do mesmo pacote.[/quote]

Então tá explicado

Na ordem do mais abrangente para o mais específico:

  • public: Pode ser acessado por qualquer classe, em qualquer pacote;
  • protected: Pode ser acessado por qualquer classe do mesmo pacote, ou por classes filhas em qualquer pacote;
  • default: Pode ser acessado por qualquer classe do mesmo pacote;
  • private: Pode ser acessado apenas na classe onde foi declarada.

Note que o Java é extremamente permissivo em relação a pacotes.

Cuidado ao pesquisar na wiki, pois modificadores de acesso variam de linguagem para linguagem, em C++, por exemplo, a regra é assim:
public: pode ser acessado por qualquer classe;
protected: Pode ser acessado na classe onde foi declarado, e nas filhas;
private: Pode ser acessado apenas na classe onde foi declarado;
classe friend: Uma classe A, que declare B como friend, dá a B o direito de acessar qualquer um de seus atributos/métodos como se fossem public, independente da forma que foram declarados.

Note que o C++ não tem modificadores especiais para os namespaces (equivalentes aos pacotes no Java).