Propriedade privada, herda ou não herda?

[quote=Schuenemann][…]
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.[/quote]

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

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.

Caralho, voces tao discutindo isso AINDA!?

[quote=Dieval Guizelini][quote=sergiotaborda]
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 ?
[/quote]
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.
[/quote]

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.

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.

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.

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.

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.

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.

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:

[quote]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. (…)[/quote]

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:

[code]public class A {
private int a=1;
private int b=1;
public void setA(int a) { this.a = a; }
public int getA() { return this.a; }
public void setB(int b) { this.b = b; }
public int getB() { return this.b; }
}

public class B extends A {
public int quadradoA() {
return this.getA() * this.getA();
}
}

public class C extends B {
public int quadradoB() {
return this.getB() * this.getB();
}
}[/code]

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

Otimo que entendeu.

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.

[quote=sergiotaborda][quote=Dieval Guizelini]
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).
[/quote]
Otimo que entendeu.
[/quote]
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).

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

O exemplo serve para os dois casos.

[quote=sergiotaborda]
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.[/quote]

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.

:lol:

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. :lol: