Propriedade privada, herda ou não herda?  XML
Índice dos Fóruns » Java Básico
Autor Mensagem
felipealbuquerque
JavaGuru
[Avatar]

Membro desde: 19/05/2006 08:19:09
Mensagens: 204
Localização: São Paulo
Offline

Uma classe A herdar de uma classe B não significa que um objeto da classe A herde de outro da classe B.
O exemplo do CPF ilustra bem essa afirmação. O pai é um objeto da A e tem um atributo privado cpf. O filho é da classe B, que estende A, portanto também tem um cpf. Não necessariamente os CPFs são os mesmos. Mas o fato é que os dois têm um CPF.
Mas... como o CPF é privado, o filho não consegue acessá-lo ao menos que haja métodos getters e setters para esse atributo, acessíveis para a classe B, definidos na superclasse. Havendo esses métodos, a edição e a obtenção desse atributo ocorrem sem problemas.

Exemplo em código:

Como podemos ver, o atributo é herdado, tanto que conseguimos acessá-lo através de métodos getters e setters. O que não podemos fazer é acessar o atributo cpf diretamente, pois não há privilégios de visibilidade suficientes para tal ação.

Espero ter conseguido expor corretamente o meu ponto de vista.

A propósito... feliz natal (antecipado) a todos!

This message was edited 1 time. Last update was at 24/12/2007 14:23:42


Felipe de Alencar Albuquerque
[MSN]
malsan
JavaChild

Membro desde: 14/12/2007 16:20:02
Mensagens: 112
Offline

Caro Irmão,
Não compreendi o lance de "ter o mesmo CPF do meu pai". A comparação não é o que se pode chamar de acertada!
Em princípio eu e meu pai não poderíamos ser de classes distintas a não ser que eu fosse algo que meu pai não é (ambos somos apenas pessoas) e não se herda valores, como o numero do CPF, mas sim atributos como ter ou não ter CPF.
Disse e torno a repetir: o fato de um membro não estar disponível não significa que o mesmo não exista. O autor do livro cometeu um pequeno engano tentando "simplificar" a coisa. Ao menos em níve de código a coisa é diferente!
Depois, quando tiver tempo, eu vou postar um código que usa reflexão (introspecção) para provar via código o que digo!
Aproveito o ensejo para desejar um Feliz e Consciencioso Natal (Kristnasko) e um 2008 de realizações!
Shalom!
San
felipealbuquerque
JavaGuru
[Avatar]

Membro desde: 19/05/2006 08:19:09
Mensagens: 204
Localização: São Paulo
Offline

Realmente esse exemplo de CPF de pai e filho dado pelo nosso amigo não foi muito legal. Mas serviu para que eu pudesse montar um exemplo... hehe.

Na verdade, um pai TEM-UM filho (ou mais).

This message was edited 1 time. Last update was at 24/12/2007 14:56:48


Felipe de Alencar Albuquerque
[MSN]
LPJava
Forum Spammer
[Avatar]

Membro desde: 18/04/2006 12:50:23
Mensagens: 3839
Localização: Bahia
Offline

felipealbuquerque wrote:Uma classe A herdar de uma classe B não significa que um objeto da classe A herde de outro da classe B.
O exemplo do CPF ilustra bem essa afirmação. O pai é um objeto da A e tem um atributo privado cpf. O filho é da classe B, que estende A, portanto também tem um cpf. Não necessariamente os CPFs são os mesmos. Mas o fato é que os dois têm um CPF.
Mas... como o CPF é privado, o filho não consegue acessá-lo ao menos que haja métodos getters e setters para esse atributo, acessíveis para a classe B, definidos na superclasse. Havendo esses métodos, a edição e a obtenção desse atributo ocorrem sem problemas.

Exemplo em código:

Como podemos ver, o atributo é herdado, tanto que conseguimos acessá-lo através de métodos getters e setters. O que não podemos fazer é acessar o atributo cpf diretamente, pois não há privilégios de visibilidade suficientes para tal ação.

Espero ter conseguido expor corretamente o meu ponto de vista.

A propósito... feliz natal (antecipado) a todos!


cara vc foi infeliz nesse exemplo, pq o fato de vc chamar um metodo e ele chamar uma variavel privada nao quer dizer que a sublclasse obteve a variavel.. o que vc fez apenas foi chamar um metodo.. e ele fez a tarefa que tem q realziar.. se chamou uma variavel private, ou se mudou o valor de um variavel isso nao importa para a subclasse, sao coisas distintas velho.. primeiro temos que aprender o conceito de "herdar".... e esse seu exemplo nao mostra isso com a variavel private... alias lembra de uma das regras do encapsulamento e de usar os metodos set e get como nomeclatura javabeans?

Bom sugiro fortemente dar uma lida no livro da kathy sobre o assunto capitulo 2.. e na minha opniao.. acho que aqui no forum, em termo academico e de experiencia profissional, nao tem no forum, profissionais com o nivel superior que o da kathy sierra para discutir que a afirmação dela está errada. Levando em conta q ela viveu dentro da sun por mais de 10 anos.. e participou de todos os projetos envolvendo java...

flw!! feliz natal!

Sun Certified Java Programmer 5.0
Blog! Atualizado 21/12 Habilidades Gerente de Projetos
http://camilolopes.wordpress.com
Colunista Java - Imasters http://www.imasters.com.br
Analyst Java Programmer - IBMistas
[WWW]
Andre Brito
Forum Spammer
[Avatar]

Membro desde: 21/07/2007 17:44:31
Mensagens: 1214
Localização: Paraná
Offline

LPJava,

Sobre o CPF, você me deixou um pouco na dúvida. Seria privado (como o nome, data de nascimento, e tal), mas não seria característica própria de cada objeto? A classe só ditaria o campo, não teria um cpf int = 2222222;. Porque na verdade, TODOS tem CPF, data de nascimento, nome e tal. Desculpe se falei algo de errado, mas esse assunto é MUITO ambíguo.

Abraço LPJava e os demais e feliz natal.

balboa is jamming.
"We couldn't find a good UML tool for our community. So our community built one. You guys are awesome."
TopCoder
Stop blaming everything (and everybody) else for your own laziness.
LPJava
Forum Spammer
[Avatar]

Membro desde: 18/04/2006 12:50:23
Mensagens: 3839
Localização: Bahia
Offline

dedejava wrote:LPJava,

Sobre o CPF, você me deixou um pouco na dúvida. Seria privado (como o nome, data de nascimento, e tal), mas não seria característica própria de cada objeto? A classe só ditaria o campo, não teria um cpf int = 2222222;. Porque na verdade, TODOS tem CPF, data de nascimento, nome e tal. Desculpe se falei algo de errado, mas esse assunto é MUITO ambíguo.

Abraço LPJava e os demais e feliz natal.


no caso do exemplo do cpf, o que foi herdado foi apenas o metodo.. faz o teste de colocar o metodo setCPF como private para vc ver... entao.. todo mundo tem um cpf.. mais nesse caso ai.. o cpf nao foi herdado por ser private.. e como coloquei na pagina anterior uma parte que a kathy fala no livro.. dela.. exatamente esse assunto e explica pq nao herdado.. o q acontece no exemplo dado, é uma caracteristica de encapsulamento e nao de herança...

para comprovar o que to falando so muda o metodo de public para private para vc ver.. que cpf nao foi herdado.

uma pergunta: seu pai herdou a cueca do seu avo? ou ele herdou apenas o que foi definido pelo seu avo?
pense nisso, pois é a mesma coisa dos membros private.

flw!

Sun Certified Java Programmer 5.0
Blog! Atualizado 21/12 Habilidades Gerente de Projetos
http://camilolopes.wordpress.com
Colunista Java - Imasters http://www.imasters.com.br
Analyst Java Programmer - IBMistas
[WWW]
Andre Brito
Forum Spammer
[Avatar]

Membro desde: 21/07/2007 17:44:31
Mensagens: 1214
Localização: Paraná
Offline

Heheh. Pois é.
A subclasse não herda visivilmente, mas veja que no meu exemplo que eu dei na página anterior o campo é herdado, posso mudar ele com métodos modificadores (mutators, como diz Deitel) e acessar o valor das mesmas com gets. Por que isso ocorre?

Meu pai não herda a cueca do meu avo (que poderia ser verde, rasgada e de tamanho x), mas herda o ter que usar a cueca (que pode ser de um tipo diferente, tipo box :p).

Abraço.

This message was edited 1 time. Last update was at 24/12/2007 17:01:39


balboa is jamming.
"We couldn't find a good UML tool for our community. So our community built one. You guys are awesome."
TopCoder
Stop blaming everything (and everybody) else for your own laziness.
LPJava
Forum Spammer
[Avatar]

Membro desde: 18/04/2006 12:50:23
Mensagens: 3839
Localização: Bahia
Offline

dedejava wrote:Heheh. Pois é.
A subclasse não herda visivilmente, mas veja que no meu exemplo que eu dei na página anterior o campo é herdado, posso mudar ele com métodos modificadores (mutators, como diz Deitel) e acessar o valor das mesmas com gets. Por que isso ocorre?

Meu pai não herda a cueca do meu avo (que poderia ser verde, rasgada e de tamanho x), mas herda o ter que usar a cueca (que pode ser de um tipo diferente, tipo box :p).

Abraço.


uhaua rpz eu desistir de explicar esse assunto eu fiquei uma manha com pardal discutindo isso hhee.. mas o procedimento do metodo é diferente cara.. muito diferente.. é uma pratica de encapsulamento que é diferente a herança.. lembra da regra de coesao e acomplamento? os dois envolve herança e encapsulamento.. .

obs.: Eu sei pq fizeram confusao com algo simples e visivel.. e se der uma lida nos conceitos de OO vai ver que a kathy está correta.. e a galera ainda permanece dizendo que herda meu deus.. uhauha

flw!

Sun Certified Java Programmer 5.0
Blog! Atualizado 21/12 Habilidades Gerente de Projetos
http://camilolopes.wordpress.com
Colunista Java - Imasters http://www.imasters.com.br
Analyst Java Programmer - IBMistas
[WWW]
ViniGodoy
Moderador
[Avatar]

Membro desde: 11/12/2006 08:22:01
Mensagens: 5516
Localização: Curitiba
Offline

LPJava wrote:certo.. visibilidade é outra coisa.. mais segundo a kathy o membro nao é herdado.. seu filho tem o mesmo cpf que vc?
se tem um campo de cadatro cpf vc vai querer colocar private nao? para que outras classes nao acesse.. o membro..
veja em anexo o que kathy diz..


O exemplo do CPF foi péssimo. Isso é o valor de um dado, de uma instância. Você e o seu filho tem um CPF e ambos os CPFs significam a mesma coisa. Isso, é a herança. A classe está relacionada a definição do atributo, não ao seu valor.

A Kathy comete um erro comum, que é justificável pelo papel que se propõe: Trocar precisão técnica por didática. É mais fácil explicar para um aluno que um atributo não é herdado. O aluno, no estágio inicial, ainda não está familiarizado com o conceito da herança e não está também muito seguro das regras de escopo e visibilidade. Ele pode começar a trabalhar esses conceitos e, mais tarde, quando tiver amadurecido, você explica o conceito com mais precisão.

Na matemática, fazemos isso desde o jardim. Na física também funciona assim. A medida que os conjuntos numéricos crescem, que as definições se aprofundam, começamos a entender mais detalhes.

Em suma, revisamos definições que são mais imprecisas, mas suficientes para nosso conhecimento na época, e as substituimos por outras mais precisas e adequadas ao nosso conhecimento atual.

Desenvolve jogos de computadores?
http://vinigodoy.wordpress.com
[WWW]
pardal_nb
Virtual Machine Man

Membro desde: 12/09/2006 08:26:06
Mensagens: 672
Offline

ViniGodoy wrote:P[...] O que ocorre se sobrescrevermos métodos privados é acabarmos com métodos de escopos diferentes. Um deles será usado quando a porção do pai invocar, outro será usado quando a porção do filho invocar que, se houvesse polimorfismo, apenas o método do filho seria invocado.


ViniGodoy,
segundo a Kathy: métodos privados não são herdados. Portanto, em uma herança, se uma subclasse criar um metodo com mesma assinatura do metodo contido na classe pai (porem com acesso PRIVATE), vc não está sobrescrevendo NADA, já que a subclasse desconhece tal metodo na classe pai...

acho meio estranho ela cometer 2 erros "grosseiros" em um mesmo capitulo ...

ViniGodoy
Moderador
[Avatar]

Membro desde: 11/12/2006 08:22:01
Mensagens: 5516
Localização: Curitiba
Offline

A subclasse herda, mas existirão dois métodos em escopos diferentes. Um na superclasse e outro na subclasse.

Um jeito fácil de demonstrar tudo isso é usar reflexão. Pegue um objeto de uma subclasse, faça reflexão em todos os níveis de sua hierarquia e você vai ver que está tudo lá, nada foi apagado. Como o Dieval ressaltou, todo objeto de uma subclasse "é uma" instância da superclasse, então, mesmo que não esteja acessível ela terá a parte privada do seu pai.

O importante é não confundir a inexistência de um método ou atributo (que ocorreria se ele não fosse herdado), com a incapacidade de acessa-lo (regra de escopo).

Desenvolve jogos de computadores?
http://vinigodoy.wordpress.com
[WWW]
pardal_nb
Virtual Machine Man

Membro desde: 12/09/2006 08:26:06
Mensagens: 672
Offline

se no exame da SCJP cair alguma questao com este problema...

o q eu marco?!
1) O q o pessoal estaá achando aki no topico (eu tb achava - ou será q ainda acho?! )?
2) O q a Kathy escreveu no livro ?

jgbt
Forum Spammer
[Avatar]

Membro desde: 04/06/2003 15:01:48
Mensagens: 1192
Localização: Porto Alegre/RS
Offline

Herda??? é visivel???
na real, qual a diferença??
como ja foi explicado N vezes no topico. herda, mas não pode ser usado diretamente por causa do escopo de visibilidade. isso é um detalhe que NUNCA interfereriu na minha vida. tem coisas mais importantes na linguagem p/ se preocupar.
p/ a prova marque SEMPRE que não herda. o livro da Kathy é bem claro, ele não ensina Java, ensina a passar na prova, é o que ela faz e MUITO bem.

[]´s

João Bier
Desenvolvedor Java
[Email]
sergiotaborda
Forum Spammer

Membro desde: 22/03/2005 20:57:48
Mensagens: 1977
Offline

ViniGodoy wrote:A subclasse herda, mas existirão dois métodos em escopos diferentes. Um na superclasse e outro na subclasse.

Um jeito fácil de demonstrar tudo isso é usar reflexão.


Relexão não é jeito de provar coisa nenhuma porque com reflexão vc pode até acessar métodos privados de outras classes.
Reflexão viola declaradamente o encapsulamento e as formas de polimorfismo. Ela faz isso de propósito, não é um erro.
Cuidado em dizer que reflexão prova alguma coisa, porque não prova. Ela foi criada exatamente para subverter as regras do compilador.

O fato da reflexão acessar aos método privados prova que ela viola as regras padrão dos modificadores de visibilidade
e isso significa que ela não pode ser usada para demonstrar como os modificadores funcionam. A mesma coisa se aplica a herança.
Métodos que manipulam metadados não podem ser usados para provar as regras a que os dados são sujeitos.

Outro exemplo: Java não permite herança multipla, mas o bytecode permite. Ferramentas de reescrita de bytecode permitem criar objetos que pertencem a duas classes simultanetamente, mas isso não significa que a linguagem java permite herança multipla.

Por outro lado o fato do método da super-classe existir no bytecode da subclasse também não prova que ele é herdado. Na realidade o codigo nem está na subclasse. Apenas parece estar. Se falarmos de attributos, claro que todos estão em todos os objetos da classe, mas isso não prova que ha herança de atributos privados.

Herança é apenas um mecanismo para expandir a visibilidade de métodos (aumentar o escopo). E por isso temos modificadores para restringir essa visibilidade. Herança não é um mecanismo de implementação é algo abstrato e conceptual: são regras.
Cada linguagem é livre de implementar os mecanismo como quiser.

Quando se fala que A extends B estamos espandindo o escopo de classe de B para A. Por padrão tudo é herdado de B para A, ou seja, por padrão todos os métodos de B são visiveis a A. Mas e se não queremos que isso seja verdade. Como restringir a herança ? como dizer que o método xxx não pode ser visivel por A, ou seja, como fazer para que xxx não seja herdado ?
Declarar que ele é privado. Só isso. Ser privado é exactamente dizer que não é herdado. É um despropósito dizer que o que é privado é herdado quando é exactamente para impedir isso que "private" existe.

Outra coisa que precisa ser lembrada é que as regras de visibilidade são reforçadas pelo compilador. Uma vez em runtime essas regras são inúteis (dai ser possível a reflexão, porque ela contece em runtime). As regras impostas pelo compilador são aquilo que compõe a linguagem java. Na linguagem java coisas privadas não são herdadas. Esse é o inteiro propósito delas serem privadas! É a restrição máxima do escopo que a herança cria. Também na linguagem java não ha multipla herança de classes.
Na plataforma java não existem restrições. Isso permite API de Reflection e manipulação de Bytecode que fazem coisas que o programador não pode fazer usando as regras normais. Por isso que são Meta-API elas fazem coisas além (meta) do normal.
Também, por isso a plataforma Java permite que outras linguagens sejam usada para geram bytecode.

Enfim ,essa conversa de que coisas privadas são herdadas não faz sentido nenhum. Basear-se na API de reflexão ou na estrutura de memória não prova nada, porque essas coisas não obedecem as mesmas regras.

Resumindo:
1)Linguagem Java e a Plataforma Java não são a mesma coisa. Têm regras diferentes.
2)API de Reflexão e manipulação de bytecode funcionam ao nivel da plataforma e não da linguagens. (Por isso se usam classes e não um sintaxe qq especial) Como tal, não podem ser usadas para provar ou desaprovar regras da linguagem. (é como dizer que grovy não tem closures porque não existem em java. Essa conversa não tem sentido)
3) Herança é uma conjunto de regras para aumentar o escopo de visibilidade dos membros da classe. Tornar as coisas privadas é negar que esse escopro aumente para aquele membro em especifico. Herança não é uma mecanismo ou uma forma de implementação. É algo que a linguagem java tem e que a plataforma java implementa. A prova que as regras da linguagem e da plataforma são diferentes é que a primeira não permite herança multipla, mas a segunda sim.
4) Dizer que coisas privadas são herdadas não faz sentido, pois "private" existe apenas para negar que o membro seja herdado (i.e. seja visivel às classes filhas).




Sérgio Taborda's Weblog
http://sergiotaborda.wordpress.com

Existe vida fora do DDD ?

MiddleHeaven Dev Blog
[WWW]
goofed
Thread.start()

Membro desde: 14/08/2007 18:18:23
Mensagens: 36
Offline

So pra contradizer melhor o exemplo do CPF do pai e do filho aqui vem um exemplo:


Nossa... Uma pessoa tem um nome... um funcionario não! ???
Pra mim, a relacao de classe nao eh tipo... pai pra filho como alguns dizem.
Que eu saiba a relacao é do famoso "é um".
Funcionario é uma Pessoa, logo Funcionario tem um atributo nome.
 
Índice dos Fóruns » Java Básico
Ir para:   
Apoiado e desenvolvido por Caelum Cursos Java - Powered by JForum 2.1.8 © JForum Team