Propriedade privada, herda ou não herda?  XML
Índice dos Fóruns » Java Básico
Autor Mensagem
Zeed01
Virtual Machine Man

Membro desde: 27/10/2006 16:44:29
Mensagens: 667
Offline

Boa tarde colegas !

Hahahahahaha !!!

Eu quero a cueca do meu pai !

Essa foi a melhor de todas !

[]s
sergiotaborda
GUJ Expert
[Avatar]

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

Dieval Guizelini wrote:
sergiotaborda wrote:
Dado que o que acontece na memoria é completamente inutil para saber se ha herança ou não , porque perder tempo com esse exemplo ?

Infelizmente não posso concordar, apenas com um conhecimento de como a ferramenta manipula a memória, IO e etc, pode-se compreender vários conceitos.


Você defende, portanto, que o que está em memoria reflete sem equivocos as regras da linaguem java ?
Vc não está pensando no problema como um todo.

Vc diz que se a classe A tem o atributo z então B que estende A também tem. A sua justificativa é que no debug (que é feito por uma ferramenta de runtime ) z aparece num objecto do tipo B.

Se A também tiver um atributo y estático ele também irá aparece em cada objecto de B. Contudo , isto não significa que y existe em cada objecto de B. Como pode um atributo (um só) pertencer simultaneamente a N objetos diferentes ?

A resposta é simples. A ferramente de debug mostra o estado do objeto, mas isso não significa que ela é limitada pelos atributos do objeto. Ela mostra tudo o que existir. Independentemente de onde.

Por outro lado , quando diz que z existe em B isso não é verdadeiro. z existe em A e B é uma expanção de A.
É como fazer um circulo à volta da são paulo e dizer que são paulo pertence ao circulo. Mas se eu fizer um circulo maior em torno do primeiro, são paulo continua petencendo ao circulo menor. Ele apenas está dentro do maior, porque este contém o menor. Estar "incluso" é diferente de "existir em"

Se aceitarmos o argumento de que z existe em B porque existe em A, porque a ferramente assim mostra, temos que aceitar que y existe em cada objecto do tipo de B, porque a ferramenta assim mostra. E isso é um absurdo porque y é estático (ele não pertence aos objetos). Logo, não podemos aceitar o argumento baseado em ferramentas de debug.

Os implementadores da ferramenta de debug poderiam ter escolhido esconder coisas estáticas. Seria mais correto do ponto de vista teorico, mas seria absurdo do ponto de vista prático. Por isso que qualquer coisas que seja uma ferramenta , ou uma API que se baseia no estado da memoria em runtime não pode ser argumento para provar o que é regra em tempo de compilação. O fato de membros privados não serem visiveis em tempo de compilação é que é a regra. E isso que significa "membros privados não são herados" ou seja, "a visibilidade de membros privados não se estende a subclasses". Privados = "só dela".




Criando sua própria API de Validação



Blog do MiddleHeaven
[WWW]
Gauss
JavaBaby

Membro desde: 12/12/2007 04:58:22
Mensagens: 88
Offline

Herda mas n eh possivel ter acesso.

O objeto n passa de uma referencia na memoria, portanto é herdado.

E isso nao vai levar em lugar algum.
Schuenemann
GUJ Ranger

Membro desde: 13/01/2005 12:31:27
Mensagens: 851
Offline

sergiotaborda wrote:
Dieval Guizelini wrote:Se for considerada uma classe pai que tenha uma propriedade com o modificador de acesso private e um método que lê essa propriedade, quando eu estender essa classe e fizer o uso desse método herdado, a propriedade que preserva a informação (declarada na classe pai como private) estará alocada na memória


Memoria = JVM = Plataforma = Implementação
Herança = Regra = Linguagem = Teoria

Linguagem é diferente de plataforma. O que acontece na memoria não tem nada a ver com a linguagem.
A prova disso é que muitas linguagens compilam o mesmo bytecode e funcionam na mesma JVM usando a mesma memoria. É dificil de aceitar isto ? Acho que não.

Dado que o que acontece na memoria é completamente inutil para saber se ha herança ou não , porque perder tempo com esse exemplo ?

O livros não afirmam que membros privados não são herados simplesmente porque querem se didáticos, eles dizem isso porque é a verdade. A prova é que dada uma classe que extende outra vc não consegue acessar nenhum dos membros privados da classe hierarquicamente superior.

Se vc acessa um método publico i ou protegido da classe pa que por sua vez acessa a variável privada , tudo bem. Isso não prova que a clase filha tem acesso à variável privada.


Eu concordo plenamente com você. Detalhes de implementação da linguagem não nos interessa e até podem mudar entre versões, sem impactar na linguagem.
Um outro exemplo é o compartilhamento de métodos pelos objetos da mesma classe.
Dieval Guizelini
Virtual Machine Man
[Avatar]

Membro desde: 05/07/2006 14:39:44
Mensagens: 570
Localização: Curitiba - PR
Offline

sergiotaborda wrote:
Vc diz que se a classe A tem o atributo z então B que estende A também tem. A sua justificativa é que no debug (que é feito por uma ferramenta de runtime ) z aparece num objecto do tipo B.

Se A também tiver um atributo y estático ele também irá aparece em cada objecto de B. Contudo , isto não significa que y existe em cada objecto de B. Como pode um atributo (um só) pertencer simultaneamente a N objetos diferentes ?

Eu não disse que a herança é justificada pela representação da informação que o debug mostra e sim pelo fato que de a classe B ao estender A, ela terá todos os recursos (propriedades e métodos) independentes da visibilidade dos mesmos.

sergiotaborda wrote:
A resposta é simples. A ferramente de debug mostra o estado do objeto, mas isso não significa que ela é limitada pelos atributos do objeto. Ela mostra tudo o que existir. Independentemente de onde.

Por outro lado , quando diz que z existe em B isso não é verdadeiro. z existe em A e B é uma expanção de A.
É como fazer um circulo à volta da são paulo e dizer que são paulo pertence ao circulo. Mas se eu fizer um circulo maior em torno do primeiro, são paulo continua petencendo ao circulo menor. Ele apenas está dentro do maior, porque este contém o menor. Estar "incluso" é diferente de "existir em"


Eu acredito que esse é o ponto principal da questão e onde surge a divergência de opniões, o fato de um círculo ter outro não significa que É o mesmo.
O problema não está no fato de eu ter duas classes que TENHAM propriedades iguais, exemplo:

Neste caso, não existe nenhuma relação entre estas classes, são classes distintas. Mas que possuem (usando o seu termo, contém) uma propriedade do mesmo tipo de informação e com o mesmo identificador. Mas não são a mesma coisa, logo:

Agora, quando temos:

independentemente do modificador, sempre as instâncias de B produzirão verdadeiro no teste abaixo:

E este é ponto para mim, ou seja, ter uma classe herdada de outra em java, implica que:
1) ela sempre passará no teste É UM;
2) ela sempre terá os recursos da classe pai, independentemente de visibilidade e da disponibilidade desse recursos para a própria subclasse ou classes terceiras.

Observe novamente que herança não está associada a idéia de pertinência ou de conter.

sergiotaborda wrote:
Se aceitarmos o argumento de que z existe em B porque existe em A, porque a ferramente assim mostra, temos que aceitar que y existe em cada objecto do tipo de B, porque a ferramenta assim mostra. E isso é um absurdo porque y é estático (ele não pertence aos objetos). Logo, não podemos aceitar o argumento baseado em ferramentas de debug.

Novamente o seu exemplo deixa claro que você está misturando o conceito de pertinência com o conceito de existência.
quando um recurso é declarado como static, esse recurso pertence a classe e está associado a todos os objetos dessa classe. Se eu criar uma subclasse, essa subclasse será também associada ao mesmo recurso. Na prática, estamos falando de uma única região de memória compartilhado por todos os objetos.

sergiotaborda wrote:
Os implementadores da ferramenta de debug poderiam ter escolhido esconder coisas estáticas. Seria mais correto do ponto de vista teorico, mas seria absurdo do ponto de vista prático. Por isso que qualquer coisas que seja uma ferramenta , ou uma API que se baseia no estado da memoria em runtime não pode ser argumento para provar o que é regra em tempo de compilação. O fato de membros privados não serem visiveis em tempo de compilação é que é a regra. E isso que significa "membros privados não são herados" ou seja, "a visibilidade de membros privados não se estende a subclasses". Privados = "só dela".


Então, para você a herança é uma regra implementada na etapa de compilação? Os objetos existem na fase de compilação?
As regras de visibilidade são validadas também em tempo de compilação, mas não somente nesta etapa. A herança e sua implementação é uma definida no nível de classe, mas as conseqüências, ou sua real implementação ocorre em tempo de execução tanto no nível de classe como de objeto.
Enquanto o código não estiver em execução, a memória não será alocada, a classe não receberá os recursos da classe pai e assim por diante.

fw

Sun Certified Java Programmer 5.0
[WWW]
Dieval Guizelini
Virtual Machine Man
[Avatar]

Membro desde: 05/07/2006 14:39:44
Mensagens: 570
Localização: Curitiba - PR
Offline

Schuenemann wrote:[...]
Eu concordo plenamente com você. Detalhes de implementação da linguagem não nos interessa e até podem mudar entre versões, sem impactar na linguagem.
Um outro exemplo é o compartilhamento de métodos pelos objetos da mesma classe.


E segundo o seu exemplo, o java poderia deixar de separar a memória em heap e stack e considerar tudo pertencente ao heap ou ao stack (implementando-os conforme as regras padrões de compiladores) e continuariamos a ter o mesmo funcionamento na passagem de parâmetros e etc.

Da mesma forma ele poderia mudar a quantidade de bytes de seus tipos primitivos, digamos que um int passa de 4 para 8 bytes, e como não é necessário conhecer a implementação eu não terei nenhuma conseqüência para as minhas aplicações, para os estudos de viabilidade, etc

Com relação a sua opnião da relevância da forma que uma linguagem implementa determinados recursos, vamos esperar um pouco e ver o quanto tempo ela dura. É a mesma coisa de dizer que todos os sistemas de arquivos são iguais e podem ser usados para qualquer solução em qualquer situação, ou que não importa como os SO são implementados...

Com relação aos métodos compartilhados, é também um padrão de implementação de compiladores, poderiamos citar aqui as DLL, os códigos nativos, os recursos de JNDI e etc, mas nada disso teria relevância para os dois conceitos em discusão, que são: herança e visibilidade dos recursos.

fw

Sun Certified Java Programmer 5.0
[WWW]
KassiPretti
JavaEvangelist
[Avatar]

Membro desde: 13/11/2007 16:28:14
Mensagens: 314
Localização: Vila Velha - ES
Offline

Eu acho que vcs estão com tanta dúvida pois estão confundindo herança com visibilidade. Temos que definir as duas coisas separadamente para entender melhor a questão das variaveis privadas.
Na verdade elas são herdadas, mas não serão visiveis ao menos se utilizarmos os métodos publics set e get delas.

Kassiane Pretti
cv
Moderador
[Avatar]

Membro desde: 04/04/2003 00:32:12
Mensagens: 7839
Localização: São Paulo, SP
Offline

Caralho, voces tao discutindo isso AINDA!?
[Email] [WWW] [Yahoo!] [MSN] [ICQ]
sergiotaborda
GUJ Expert
[Avatar]

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

Dieval Guizelini wrote:
sergiotaborda wrote:
Vc diz que se a classe A tem o atributo z então B que estende A também tem. A sua justificativa é que no debug (que é feito por uma ferramenta de runtime ) z aparece num objecto do tipo B.

Se A também tiver um atributo y estático ele também irá aparece em cada objecto de B. Contudo , isto não significa que y existe em cada objecto de B. Como pode um atributo (um só) pertencer simultaneamente a N objetos diferentes ?

Eu não disse que a herança é justificada pela representação da informação que o debug mostra e sim pelo fato que de a classe B ao estender A, ela terá todos os recursos (propriedades e métodos) independentes da visibilidade dos mesmos.


Mas como vc prova que tem ? Esse é o ponto.
Várias pessoas apresentam a prova usando mecanismos de debug, uso de memória, profilers, etc... ou seja, ferramentas de runtime que interagem com a JVM.

Acho que ficou claro que esse tipo de ferramentas não pode provar coisa alguma sobre a estrutura dos objetos em memoria. Elas mostram aquilo para que foram criadas e não a estrutura real na memoria.

1)Para que se aceite que B tem todos os recursos de A é necessário provar isso. Sendo que o uso de ferramentas não prova isso, não se pode (agora/ainda) aceitar que B tem todos os recursos de A.

2)Mesmo aceitando que B tem os recursos de A isso não acontece porque A é copiando para B e acrecentado de mais coisas. Acontece porque B é A. Sendo assim, tudo aquilo que é de A é de B. Tudo, exceto o que é apenas de A, obvio.


Agora, quando temos:

independentemente do modificador, sempre as instâncias de B produzirão verdadeiro no teste abaixo:

E este é ponto para mim, ou seja, ter uma classe herdada de outra em java, implica que:
1) ela sempre passará no teste É UM;


Objectos do tipo B sempre são objetos do tipo A. Aqui não ha dúvidas. Isso é herança: construir tipos a partir de outros. O ponto em causa é são os membros privados de A.


2) ela sempre terá os recursos da classe pai, independentemente de visibilidade e da disponibilidade desse recursos para a própria subclasse ou classes terceiras.


Não, não terá. E é isso que tem que ser provado.
Entende que se eu declaro algo private em A e isso existe em B então não é mais private em A; Não é mais interno a A, é agora compatilhado com B. A noção que algo privado pertence a algo mais que o seu proprio dono é absurda. Ela fere o conceito de encapsulamento que é o conceito mater em OO. As coisas são feitas privadas exactamente para que não existam em outros lugaes.

Mas o que significa "existir" em OO. Nada.
As coisas não "existem" elas são definidas em alguma lugar, e acessadas em outro. Ou melhor, elas são criadas e acessadas em u detirmado escopo. Falamos que existe como forma de simplificar, mas na realidade isso não existe.


Então, para você a herança é uma regra implementada na etapa de compilação? Os objetos existem na fase de compilação?


A herança é entre classes (tipos), logo não ha necessidade de objetos e portanto não ha necessidade de runtime.

As regras de herança não são implementadas na compilação, elas ão forçadas na compilaçao.


As regras de visibilidade são validadas também em tempo de compilação, mas não somente nesta etapa.


Sim, somente nessa etapa.
Em runtime elas não são verificadas porque elas não existem em runtime. É por isso que a API de reflection funciona. E ai as regras são forçadas via API e passando pelo SecurityManager. Se o SecurityManager travar o acesso a coisas privadas vc não consegue acessar e ponto final.
Como eu já disse a JVM não força regras ela faz as coisas funcionar. Quem força regras é o compilador porque é no compilador que se define uma linguagem.


A herança e sua implementação é uma definida no nível de classe, mas as conseqüências, ou sua real implementação ocorre em tempo de execução tanto no nível de classe como de objeto.
Enquanto o código não estiver em execução, a memória não será alocada, a classe não receberá os recursos da classe pai e assim por diante.


O ponto é esse. A classe receber os recursos da classe pai não significa que ha herança. Significa apenas que o estado do objeto precisa daquelas variáveis. Lembre-se que os métodos nem sequer existem na memoria.

Resumindo:
1)Herança é um conceito teorico que visa produzir tipos com base em outros existentes. Para isso ela aumenta o escopo da definição dos membros da classe.
2)Nem sempre tudo o que é de uma classe pode ser passado aos filhos. Por isso existe uma restrição que permite declarar uma variável apenas no escopo da classe onde ele é definida de forma que ela não pertence ao escopo da classe filha. Deste modo a classe filha não pode acessa essa variável. O uso de "private" garante, implica e foi criado para retirar a variável da herança. Serve para dizer "filho, isto, tu não herdas".
3)Se a variável compoe o estado do objeto e o objeto é algo na memoria, provavelmente a memoria contém todas as variáveis privadas da hierarquia da classe do objeto, mas não ha forma de provar isso. Ferramentas de debug e afins não servem para provar a estrutura de memoria que a JVM usa (alías esse é todo o objetivo da JVM : encapsular a implementação)
4) Mesmo que as ferramentas mostrassem a real estrutura, e mesmo que essa estrutura contenha as variáveis privadas isso de deve ao facto da classe filha ser a classe pai, logo a variável está ali, porque o pai está ali.
Ele está, pertence, existe, é definida apenas no pai. nunca no filho. O objecto é definido pelo primeiro pai (objet) e acrescentado de todos os outros membros das classes filhas.

Enfim: membros private não são herdados.
É um contrasenso e um absurdo dizer que são. Esse é todo o objetivo deles serem declarados private.

----

Java tem uma excelente sintaxe porque é simples. com poucas palavras chave.
Poderiamos pensar que numa sintaxe maior a restrição de herança fosse definida com outra palavra
por exemplo "notinherit". Seria mais explicito que aquele menbro não será herdado. Isto continuaria produzindo em memoria uma estrutura completa, porque "herdar" não significa "existe na memoria", significa "existe no escopo". Java é muito mais limpo na sintax e impede a herança de membros com private e a herança de classes com final.


This message was edited 1 time. Last update was at 11/01/2008 19:56:27


Criando sua própria API de Validação



Blog do MiddleHeaven
[WWW]
Dieval Guizelini
Virtual Machine Man
[Avatar]

Membro desde: 05/07/2006 14:39:44
Mensagens: 570
Localização: Curitiba - PR
Offline

Sergio,

Quando estava lendo para acrescentar mais algum argumento em prol da minha teoria, econtrei um trecho no livro Java: O Guia essencial de David Flanagan que coloca esta questão dessa forma:
A especificação de java afirma que uma subclasse herda todos os campos de instância e métodos de instância (...)
A afirmação de que uma subclasse não herda os campos e métodos inacessíveis de sua superclasse pode gerar confusão. Aparentemente, essa afirmação indicaria que, quando você cria uma instância de uma subclasse, nenhuma memória é alocada a qualquer campo private definidos pela superclasse. Essa, porém, não é a intenção da afirmação. Cada instância de uma subclasse inclui, de fato, uma instância completa da superclasse dentro dela, incluindo todos os campos e métodos inacessíveis. Trata-se apenas de uma questão de terminologia. Como os campos inacessíveis não podem ser utilizados na subclasse, dizemos que eles não são herdados. (...)


A questão para mim ficou clara com relação ao sentido semantico, o conceito de herança está sendo associado a questão de usuabilidade pela subclasse e não da forma que eu vejo (que é quanto a composição ou consistência).

A diferença desses dois contextos, apresenta-se de forma clara no exemplo a seguir:



Se os campos private não fossem herdados (estruturalmente), os métodos que fazem uso dos recursos getA e getB não poderiam funcionar, simplesmente porque o espaço de memória para os campos a e b não deveria existir.

fw

Sun Certified Java Programmer 5.0
[WWW]
sergiotaborda
GUJ Expert
[Avatar]

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

Dieval Guizelini wrote:
A questão para mim ficou clara com relação ao sentido semantico, o conceito de herança está sendo associado a questão de usuabilidade pela subclasse e não da forma que eu vejo (que é quanto a composição ou consistência).


Otimo que entendeu.


Se os campos private não fossem herdados (estruturalmente), os métodos que fazem uso dos recursos getA e getB não poderiam funcionar, simplesmente porque o espaço de memória para os campos a e b não deveria existir.


Ora ai é que está. Funcionaria sim. Leia a sua citação de novo:
"Cada instância de uma subclasse inclui, de fato, uma instância completa da superclasse dentro dela, incluindo todos os campos e métodos inacessíveis"

Imagine dois retangulos . um menor a classe pai e um maior a classe filho. O maior não é um outro retangulo cujo conteudo foi copiado do pai e acrecentado de novas coisas. O maior é o pai acrecentado de novas coisas (sem copia). Então os campos podem não ser herdados e continuaram pertencendo na estrutrura do filho. Aliás , seria absurdo se não pertencecem.A diferença é que a estrutura do filho não é uma copia do pai e sim o pai em si mesmo. Assim asseguramos que os campos que pertencem a um nivel da hirarquia pertencem apenas a esse nivel.

Ainda bem que estamos esclarecidos quanto ao significado de herança e que ele nada tem a haver com estrutura na memoria.

Portanto, membros privados não são herdados.

Criando sua própria API de Validação



Blog do MiddleHeaven
[WWW]
Dieval Guizelini
Virtual Machine Man
[Avatar]

Membro desde: 05/07/2006 14:39:44
Mensagens: 570
Localização: Curitiba - PR
Offline

sergiotaborda wrote:
Dieval Guizelini wrote:
A questão para mim ficou clara com relação ao sentido semantico, o conceito de herança está sendo associado a questão de usuabilidade pela subclasse e não da forma que eu vejo (que é quanto a composição ou consistência).

Otimo que entendeu.

Eu compreendi o seu ponto de vista, não afirmei que o meu estava errado, e enquanto entedimento e interpretação do conceito de herança continuo defendendo o meu ponto de vista. Eu apenas encontrei uma literatura que descreve formalmente as diferenças de opnião.
O seu foco, para interpretação do conceito de herança, está na usuabilidade do recurso.
O meu foco, para interpretação do conceito de herança, está na existência do recurso (presente na classe filha, independente de estar acessivel diretamente ou não).

sergiotaborda wrote:

Se os campos private não fossem herdados (estruturalmente), os métodos que fazem uso dos recursos getA e getB não poderiam funcionar, simplesmente porque o espaço de memória para os campos a e b não deveria existir.

Ora ai é que está. Funcionaria sim. Leia a sua citação de novo:
"Cada instância de uma subclasse inclui, de fato, uma instância completa da superclasse dentro dela, incluindo todos os campos e métodos inacessíveis"

A afirmação não é minha, é do David Flanagan.

sergiotaborda wrote:
Imagine dois retangulos . um menor a classe pai e um maior a classe filho. O maior não é um outro retangulo cujo conteudo foi copiado do pai e acrecentado de novas coisas. O maior é o pai acrecentado de novas coisas (sem copia). Então os campos podem não ser herdados e continuaram pertencendo na estrutrura do filho. Aliás , seria absurdo se não pertencecem.A diferença é que a estrutura do filho não é uma copia do pai e sim o pai em si mesmo. Assim asseguramos que os campos que pertencem a um nivel da hirarquia pertencem apenas a esse nivel.

O exemplo serve para os dois casos.

sergiotaborda wrote:
Ainda bem que estamos esclarecidos quanto ao significado de herança e que ele nada tem a haver com estrutura na memoria.
Portanto, membros privados não são herdados.


A afirmação em negrito é a sua interpretação do conceito para a forma com que o Java implementa o recurso de herança.

Como vivemos em uma democrácia, podemos conviver com as duas interpretações, e diria mais, que elas, na essencia, são complementares. Pois temos o aspecto da existência da estrutura de informação que está mais do que demonstranda que na classe filha recebe (herda) todas as características definidas na classe pai (independente da visibilidade). E com relação a usuabilidade desses recursos, podemos aceitar o fato que a classe filha não herda da classe pai os recursos, simplesmente pelo fato deles não estarem disponíveis para serem acessados diretamente.

Logo, para mim, a definição do conceito de herança para recursos privados, é melhor descrito como:

Uma subclasse recebe todos os campos e métodos da classe pai, porém os recursos privados (private) definidos na classe pai não estarão acessíveis diretamente pela subclasse.

Teremos ainda que ampliar a definição da exceção para recursos que são declarados sem o uso de um dos modificadores de acesso (public, private protected) para subclasses que não estejam no mesmo package da classe pai.


Sun Certified Java Programmer 5.0
[WWW]
alps
HelloWorld
[Avatar]

Membro desde: 12/07/2008 13:26:21
Mensagens: 11
Offline

Galera, o negocio é o seguinte.. Ao meu ver, os modificadores public, privated, protected etc... não controlam nada a respeito de herança e sim e somente a respeito de visibilidade externa (public: visivel para todos, privated: oculto para todos e protected: visivel para os filhos da classe) Tanto que se vc fizer uma classe Pessoa com atributos nome e idade PRIVADOS, mas contruir os getters e setters PROTEGIDOS (protected) vc poderá ter acesso a estes atributos por um objeto filho que por definição herdará todas as propriedades de sua SuperClass.
 
Índice dos Fóruns » Java Básico
Ir para:   
Powered by JForum 2.1.8 © JForum Team