Membro Privado é herdado, mas não é visível!
Engenharia de SW March 5th, 2008[EDITADO]
Após alguns comentários, resolvi buscar outras fontes de leitura. E estou convencido de que errei. Membro privado não herda. :$
[/EDITADO]
Meses atrás houve um grande debate entre alguns amigos sobre a seguinte questão:Afinal, métodos e propriedades privados em java, são herdados pelas classes-filhas?
Tem gente que acredita que herda, tem gente que acredita que não herda e tem gente que não acha nada!
Estou no grupo que acredita que herda!
Qualquer membro que tenha sua visibilidade marcada como private, é herdada pelas classes-filhas.Porém, somente a classe onde o membro foi declarado terá acesso (devido ao tipo visibilidade).
Este é um bom assunto para juntar um grupo de amigos e discutir. Certamente iniciará uma Flame War :X
Vou tentar convencer vocês a acreditarem que herda .
Retirado do wikipédia, de forma resumida, o conceito de herança é:
“A Herança é um princípio da Programação Orientada a Objetos que permite que as classes compartilhem atributos e operações baseados em um relacionamento, geralmente generalização. A herança permite a criação de subclasses que herdam atributos e operações (ou Métodos) da classe pai (super-classe ou classe base) “
Do meu ponto de vista, o que ocorre, em Java especificamente, é o seguinte:
Herança é uma coisa, e escopo de um membro é outra. Quando tornamos um membro “private”, estamos falando que o seu escopo é apenas dentro da própria classe. O que é totalmente diferente de: Os objetos das classes-filhas não herdaram este(s) membro(s).
O grupo que acha que não herda alega que as propriedades não estão presentes na classe filha, não são visíveis.
Durante a “discussão” herda, não herda, nos deparamos com opiniões de outras pessoas. Vimos que toda a estrutura das classes são alocadas em memória e prontas para serem utilizadas pelos mecanismos internos da classe. Ou seja, os membros estão lá. É fato que não é possível acessar de forma direta os membros privados da superclasse, a não ser que seja via reflexão. O que foge da discussão aqui.
Uma outra coisa que é legal comentar é que, não existe polimorfismo com membros privados. Caso exista um membro de mesmo nome nas classes-filhas, este será apenas um novo membro com escopo diferente.
Este, talvez, seja o motivo da GRANDE confussão, já que quando estamos implementando a classe-filha temos a sensação de que os membros privados não são herdados.
March 5th, 2008 at 12:43 pm
uhauha nem vou mais dizer nada sobre isso.. eu sou uma das pessoas que particiupo do debate heim? deu ate dor de cabeça.. mais assim.. vc herdou a cueca do seu pai, que seu pai herdou do pai dele? Não pq a cueca é algo private pertence apenas a class Pai, class Avo, class Bisavo.
flw!
March 5th, 2008 at 6:37 pm
public class A{
private String n = “teste”;
}
public class B extends A{
public String getN(){
return n;
}
}
Resultado:
\> javac A.java
A.java:7: n has private access in A
return n;
^
1 error
Portanto, propriedade privada não é herdada pela classe filha. Independente de como seu valor está armazenado. Se “(…)os membros estão lá (…)”, como você diz, é porque precisam estar lá para ser possível acessar os valores da classe pai, que são privados, usando super. Como:
public class B extends A{
public String getN(){
return super.n;
}
}
March 5th, 2008 at 7:33 pm
Crie um método public na classe pai que acessa um membro privado dessa mesma classe. Chame esse método na classe filha. Acontecerá a mesma coisa que se chamado na classe pai. Ou seja, o membro está lá. Apenas não está visível diretamente.
Outro teste. Faça um construtor na classe pai que inicializa um membro privado (atributo). Chame esse construtor no construtor da classe filha (com super()). Obviamente o membro será inicializado, só que, mais uma vez, indiretamente.
Ou seja, se a coisa está lá, então ela foi herdada.
Não esqueçam também da palavrinha EXTENDS. Ela quer dizer, é tudo que já tinha e mais um pouco.
March 6th, 2008 at 12:00 pm
@Rodrigo Rebouças
Você copiou um trecho do que eu escrevi, mas não o conceito como um todo. O que você tem que fazer é exatamento o que a scilla falou: “Crie um método public na classe pai que acessa um membro privado dessa mesma classe.”
Não podemos esquecer o conceito de HERANÇA e VISIBILIDADE. São coisas completamente diferentes.
[]’s
June 16th, 2008 at 12:25 am
Questão interessante. Canonicamente a resposta simples é não, não herda. Segundo a Java Language Specification:
Mas o que isso quer dizer é que a sub-classe não conhece o método privado, podendo inclusive declarar outros métodos com mesmo nome.
O exemplo do Scilla acima mostra que os métodos que são herdados possuem acesso aos métodos que não são herdados. É uma zona cinza interessante, creio.