Essa é boa!

8 respostas
M

gente, essa eu duvido alguém matar de primeira, mas antes uma revisão, sabemos q qnd o membro de uma classe é protected ele é visivel somente pelas classes de mesmo pacote, e por subclasses atravéz da herança, se a subclasse estiver num pacote diferente, só poderá acessar o membro protected atravéz de herança, sem exceções… Agora, se temos uma classe declarada em um pacote X, q extends uma classe com um membro protected do pacote Y, esse membro se torna private na subclasse, não sendo possível outras classes do pacote X acessá-lo, certo? bem, pra simplificar, vai um exemplo:

Superclasse em package com.foo

package com.foo;

public class Father {

   protected int x;

}

Subclasse em package com.foo.chield

package com.foo.chield;

import com.foo.Father;

public class Chield extends Father {

}

ok, até ai td jóia, a variável de instância “x” vai se tornar um membro private da classe Chield, MAS… e se eu escrever uma classe com.foo.Neighbor, no mesmo pacote de Father, e tentasse acessar a variável “x” por meio de uma referência a Chield? assim:

package com.foo;

import com.foo.clield;

public class Neighbor {

   public Neighbor() {

      Chield chield = new Chield();

      chield.x = 10; // isso daria certo? >:)
   }

}

…O problema é bem intrigante, eu estava lendo o livro da Kathy sobre os niveis de acesso, e me surgiu essa dúvida q o livro não aborda… fui pro Eclipse testar, confesso q o resultado me surpreendeu, até classifiquei como um bug!

8 Respostas

J

Vamos lá…

Isso de vc falar que ele será private para a classe que herdar, não é está certo… porque?

Porque como vc mesmo disse o atributo x da classe Father é protected. Então todos as classes que estiverem no mesmo pacote ou herdar terão visão dela. Pois bem, a classe Chield (que esta em outro pacote) herda de Father. Portanto, dentro da classe mesmo não estando no meu pacote, ela será visivel (pelo conceito). Olha o interessante agora, a classe Chield é uma Father (Pelo conceito de herança), então se Chield for instânciada em um classe que esteja no mesmo pacote, não terá problema (pelo conceito de protected, que qq classe do mesmo pacote terá visão). Sendo assim, como a classe Neighbor, está no mesmo pacote, não terá problema, irá ter visão do atributo x.

Agora, tente colocar a classe Neighbor em outro pacote… erro.

Certo?

M

nao nao javateco, tu nao me entendeu cara, esse atributo "x" vai se tornar private a nivel de q quem estiver no mesmo pacote q Child, nao poderá acessar o "x" como se fosse protected, assim, Chield esta em um pacote diferente e herdou o "x" de Father, beleza, esse "x" é protected em Father, mas agora com ele em Chield em outro pacote, nao tem como uma classe q seja do mesmo pacote de Chield conseguir acessar esse "x" como se ela continuasse sendo protected, assim:

package com.foo.chield; 

import com.foo.Father; 

public class Chield extends Father { 
  // herdou o "x", legal...
}
//mesmo package q Chield
package com.foo; 

public class Neighbor { 

   public Neighbor() { 

      Chield chield = new Chield(); 

      chield.x = 10; // ERRO!!!!   
   } 

}

entendeu? não é esse ponto q eu quero chegar, é q Neighbor esta no mesmo pacote q Father, e acessando o "x" de Chield como se fosse protected e estivesse na mesma classe q Chield! mas não está! (no primeiro exemplo q mandei), entendeu?

J

Entendi…

Ai concodor… se for no pacote com.foo.chield, pois o x da classe Father está em outro pacote, mas isso não quer dizer que ele esteja private, é o conceito de protected

Continuo com a mesma opnião… Neighbor está no mesmo pacote de Father, certo? E ele (classe Neighbor) tem uma referência para a classe Chield, certo? O objeto da classe Chield pode perfeitamente acessar o atributo x, pois o objeto está no mesmo pacote de Father.

Faça o teste da classe abaixo…

Isso aqui sim é erro, pq o objeto da Chield não está no mesmo pacote:

import com.foo.chield.Chield; 

public class Neighbor { 

   public Neighbor() { 

      Chield chield = new Chield(); 
      chield.x = 10;

   } 

}

O realmente eu ainda não entendi a pergunta… :wink:

M

então, ai q tá cara… Neighbor esta no pacote de Father, acessando o “x” com uma referencia a Chield, de pacote diferente, se ele tivesse uma referencia de Father e tentar acessar o “x”, td bem, estão os 2 no mesmo pacote, mas com uma referencia a Chield, q esta em um pacote diferente, acessar o “x”… bah, eu acho q deveria dar erro, mas não… o código executa perfeitamente, é como se o “x” fosse sempre visivel naquele pacote, mesmo usando uma referencia a uma classe de outro… :roll:

F

claro q funciona, olha soh, Chield é um Father, portanto, seria inutil restringir o acesso, era soh por assim:

Chield c = new Chield();
((Father)c).x = 32;

dessa forma ta acessando o membro do Father pelo Father, eh a mesma coisa q uma classe q acessa seu proprimo membro private com uma instancia a si mesma…

Protected eh acecivel no mesmo package e na heranca, n importa em qual package Chield esta, o q importa eh q a variavel x esta na classe Father q esta no mesmo pacote q Neighbor, portanto eh acessivel, se foce do jeito q vc ta falando, as classes no mesmo pacote de Chield poderiam acessar livremente a variavel x…

M

ta então tem q prestar atenção no escopo do objeto, e não necessariamente qual o pacote dele, como o javateco me disse no icq… mas mesmo assim, se caísse uma dessas, eu diria q não compilava na hr 8O

eltonk

E se a classe Neighbor estivesse em outro pacote, com por exemplo com.foo.neighbor?
Porque não teria acesso a x através de Chield?

Ok… Protected somente é acessivel através dos filhos e mesmo pacote. No caso anterior o acesso era permitido por que estava no mesmo pacote.
E neste caso, porque é negado?
Protected vira Private em Chield, quando extendido?

S

“eltonk”:
E se a classe Neighbor estivesse em outro pacote, com por exemplo com.foo.neighbor?
Porque não teria acesso a x através de Chield?

Porque está num pacote diferente de Child.

Um membro protected só é acessado de 3 formas:
1- Dentro da própria classe.
2- Tendo uma referência ao objeto da classe, no mesmo pacote.
3- Por herança. A subclasse pode estar em qualquer pacote.

“eltonk”:
Ok… Protected somente é acessivel através dos filhos e mesmo pacote. No caso anterior o acesso era permitido por que estava no mesmo pacote.
E neste caso, porque é negado?
Protected vira Private em Chield, quando extendido?

Sim, se Child estiver em outro pacote.

Olha só o exemplo do livro.
Classe pai:

package certification; public class Parent { protected int x = 9; // protected access }
Classe filha:

package other; // Different package import certification.Parent; class Child extends Parent { public void testIt() { System.out.println("x is " + x); // No problem; Child inherits x Parent p = new Parent(); // Can we access x using the p reference? System.out.println("X in parent is " + p.x); // Compiler error! } }

So far we’ve established that a protected member has essentially package-level or
default access to all classes except for subclasses. We’ve seen that subclasses outside
the package can inherit a protected member. Finally, we’ve seen that subclasses
outside the package can’t use a superclass reference to access a protected member.
For a subclass outside the package, the protected member can be accessed only through
inheritance.
But there’s still one more issue we haven’t looked at…what does a protected
member look like to other classes trying to use the subclass-outside-the-package to
get to the subclass’ inherited protected superclass member? For example, using our
previous Parent/Child classes, what happens if some other class—Neighbor, say—
in the same package as the Child (subclass), has a reference to a Child instance and wants to access the member variable x ? In other words, how does that protected
member behave once the subclass has inherited it? Does it maintain its protected
status, such that classes in the Child’s package can see it?
No! Once the subclass-outside-the-package inherits the protected member, that
member (as inherited by the subclass) becomes private to any code outside the
subclass. So if class Neighbor instantiates a Child object, then even if class Neighbor
is in the same package as class Child, class Neighbor won’t have access to the Child’s
inherited (but protected) variable x. The bottom line: when a
subclass-outside-the-package inherits a protected member, the member is essentially
private inside the subclass, such that only the subclass’ own code can access it.

Criado 10 de julho de 2004
Ultima resposta 8 de mai. de 2006
Respostas 8
Participantes 5