Quebra de encapsulamento na linguagem java

5 respostas
D

Gurus do forum, estou com uma duvida e tenho certeza que alguem aqui pode me explicar. Antes vou colocar o código que me causou a duvida.

public class B extends A {}
public class A {
private int a = 2;
public static void main (String[] args)
{
A teste = new B();
system.out.println(teste.a);
}
}

Resumindo, criei uma classe A e a extendi numa classe B. Dentro desse classe A tenho um membro privado chamado “a” cujo valor iniciei com 2.
Na classe A tenho um metodo main onde criei um objeto da classe B e o atribui a uma referencia da classe A. Até onde eu entendo o objeto da classe B não possui o membro a. Mas o código compila e é printado na tela o valor 2.

Estou raciocinando errado? Qndo eu crio um objeto B ele “possui” os membros da superclasse A mesmo eles sendo privados?
Pq pelo q eu entendo, e claro q posso estar errado, eu criei um objeto do tipo B que não possui o membro a, isso seria uma quebra de encapsulamento.

5 Respostas

LPJava
vc está se confudido.. private é daquela classe e pronto.. a class B nao sabe que o seu primitivo que vc criou la existe... esse codigo na verdade nao compila observe como está sua impressão.. system alterar para System. Bom mais voltando a sua duvida... o fato de imprimir ai eh pq qdo vc faz isso:
A teste = new B();
[/code
vc criou uma instancia de B o qual é do Tipo A.. mas ja que faz tudo que A faz tranquilo ai... mas quando vc chama [b]teste.b[/b] ele chama o do tipo e nao da instancia..como a class A tem a variavel que vc ta referenciado entao tranquilo  veja isso simplificado:
[code]
class Animal{
void cor(){}
}
class Zebra extends Animal{
void idade(){}
void cor(){}
}
class Principal{
public static void main(String args[]){
Animal a = new Zebra();
a.cor();//isso compila ele chama o da class Zebra
Animal b = new Zebra();
b.idade();//isso nao vai Animal nao tem esse metodo

pq a segunda instancia nao funciona? pq a class Animal nao reconhece o metodo idade() entao nao tem como ela executar isso... e nao passa no teste É-UM.. que é o ideial.. entao quando vc extends LEMBRE-SE quem extende so pode chamar aquilo que seu PAI tem.. ou os seus proprios metodos..
[i] uma ZEBRA ÉUM animal mais uma ANIMAL nao pode ser uma zebra, pq animal pode ser qualquer coisa, Cachorro rato....percebe-se ai? a diferença...

bom espero ter ajudado.. qualquer coisa so gritar!!

ViniGodoy

Acontece que a classe A conhece o atributo a.

Seu main está na classe A e sua instância (embora tenha sido iniciada com B) está sendo referenciada por A.

Portanto, o atributo privado é visível, já que se trata de um acesso dentro da própria classe.

D

Camilo, acho q eu não entendi muito bem sua explicação, enfim, a explicação do Vini ficou mais clara, embora eu ache q isso é uma quebra de encapsulamento. Estou falando aqui de conceitos OO, esse codigo q eu criei nao compilaria em C++, mas em java compila.
Tudo bem q o acesso é feito dentro da classe A mas o objeto é uma instancia de B que nao possui a visibilidade necessaria para aquele membro.

ViniGodoy

Não é uma quebra do encapsulamento.

Veja bem, a classe A pode acessar todo e qualquer conteúdo privado de um objeto da classe A, correto? Afinal, o privado é para objetos da própria classe.

Entretanto, embora sua instância seja de B, vale lembrar que a relação de herança estabelecida diz que a classe B é um A. Ou seja, todo objeto da classe B é também um objeto da classe A (o contrário não é verdadeiro).

Portanto, a classe A, pode acessar os membros privados de B, desde que sejam declarados na própria classe A. É como se A conseguisse ver “a metade A de B”. Isso porque, repetindo, todo B é também um A.

E até onde eu me lembro, o C++ também não é uma implementação muito fiel da OO. Por lá existem classes “friend” e castings que simplesmente violam o bom senso (tal como um carro de dados byte[] qualquer para uma classe, desde que o número de bytes “combine”). Além do fato de você poder ter métodos não polimórficos fazendo “shadowing” e criando a situação estranha do comportamento dele mudar de acordo com o tipo da variável que o referencia…

Não estou desmerecendo o C++. Por mim, é uma das melhores linguagens já inventadas, só quero ressaltar que ela não pode ser colocada como um parâmetro de uma excelente implementação dos conceitos OO.

No java também não gosto da abordagem do encapsulamento em termos de pacotes… tudo é público num mesmo pacote, exceto o private.

Violar ou não o encapsulamento, no caso da OO, está mais relacionado ao projeto de seu sistema, não tanto em como a linguagem implementa os modificadores de acesso. Uma vez que a linguagem tenha o suporte básico aos modificadores publicos, privados e protegidos, você pode implementar o encapsulamento e não serão detalhes de interpretação da regra como esses que irão comprometer o seu sistema.

O fato é que, tem gente encapsulando pouco e xunxando em todas as linguagens e assim como existem sistemas muito coesos e encapsulados em ambas as linguagens.

pcalcado

Exatamente. Encapsulamento tem muito pouco a ver com a existência de membros privados.

Criado 10 de março de 2007
Ultima resposta 12 de mar. de 2007
Respostas 5
Participantes 4