Propriedade privada, herda ou não herda?

Pessoal,

Existe uma diferença entre a existência de um atributo e a sua visibilidade.

O que o Dieval quer dizer é que, uma classe filha herdará um atributos e métodos do pai, no sentido de que, essas estruturas existirão, serão alocadas em memória, e serão usadas pelos mecanismos internos da classe. Afinal de contas, o filho é um objeto da classe pai e nada mais natural do que ele ter absolutamente todos os atributos do pai.

Entretanto, graças às regras de escopo, esses atributos e métodos não serão visíveis na classe filha. Daí a confusão. Assim, eles são herdados (pq existem e são acessados indiretamente pelos filhos), mas não são visíveis, estão fora do escopo da classe filha.

Por isso, não é possível fazer polimorfismo de métodos privados, por exemplo. 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.

Isso é o que realmente acontece. Agora, a sensação para quem implementa um filho é de que os atributos e métodos privados não existem. Por isso tantos livros dizerem que não são herdados. Vai muito do que o autor considerar ou não herança.

Com relação a kathy,

existem dois pontos, a forma com que ele escreve e para qual objetivo. Para o iniciante pode ser interessente ele ter a idéia de que não acontece a herança para entender o escopo de visualização, mas não a forma de implementação interna e quanto mais com relação a teoria de OO.

Outro ponto, você está se baseando em uma informação traduzida de má qualidade. Procure aqui mesmo no GUJ e você irá verificar que os tradutores fizeram um péssimo trabalho…

É como o Vini falou.

fw

Ps: felipealbuquerque recomendo que você veja o meu exemplo anterior, você está equivocado. O seu exemplo mostra o nível de controle sobre o escopo do recurso e não significa que a herança não ocorreu.

Não tem como Herdar membros privados… por isso tem os Gets e Setters!

Abraços!

[quote=truck1n][quote=Dieval Guizelini]

  1. herança sempre herda tudo (absolutamente tudo) da classe pai.
    [/quote]

Não tem como Herdar membros privados… por isso tem os Gets e Setters!

Abraços![/quote]

Vocês estão andando em circulos…

os métodos são apenas “interfaces” entre os estados internos de um objeto (propriedades, variáveis de instâncias, tipos primitivos) e o mundo externo (outros objetos). Os métodos por si só não são capazes de PRESERVAR a informação.
Quando se cria uma instância de uma subclasse ela possui TODAS as características da classe pai, por isso ela pode ser comparada com o operador instanceof da classe pai e ter como resultado verdadeiro, pois este operador verifica que objeto (de uma subclasse) É uma instância da classe pai, o que é muito diferente de TER um membro de uma determinada classe.

Logo o fato de um ou mais recursos serem declarados como private não impede destes mesmos recursos estarem presentes (fazerem parte) das instâncias de classes filhas. Não está em discussão se estes recursos são ou não acessíveis através destas instâncias e apenas se eles são ou não HERDADOS.

fw

[quote=truck1n][quote=Dieval Guizelini]

  1. herança sempre herda tudo (absolutamente tudo) da classe pai.
    [/quote]

Não tem como Herdar membros privados… por isso tem os Gets e Setters!

Abraços![/quote]

ACHO que você tem razão… Me deixou na dúvida agora… se eu tenho uma variável de instância j private, usar um getJ e um setJ(tipo novoJ), eu posso acessar com o get e setar com o set? Então ela é tanto visível quanto pode ser modificada e manipulada, concorda?

dedejava,

em partes,

você deve lembrar que os métodos podem realizar validações, e eventualmente não modificar o conteúdo da variável. Exemplo o CPF, você pode ter um método setCPF que valide a informação passada e se ela não passar pelo algoritmo de validação ela não será atribuída a propriedade cpf.
Na prática, os set e gets são recomendados principalmente para quando você precisar incluir alguma validação ou gerar um “evento/notificação” de modificação ou de acesso possa ser implementado a posteriori. Ou por exemplo, para se modificar o domínio ou realizar qualquer modificação interna no objeto sem a necessidade de reescrever todos as classes e objetos que façam uso destes recursos.
O legal de se compreender as definições de OO, é que se bem utilizados os métodos como interfaces das propriedades, você poderá modificar com relativa segurança quase tudo do seu objeto sem impactar nos outros pontos do sistema. O outro ponto é que a propriedade pode ser relevante para outros valores/estados do próprio objeto.

fw

Eu fiz os seguintes códigos:


/**
 * Write a description of class Superclasse here.
 * 
 * @author (your name) 
 * @version (a version number or a date)
 */
public class Superclasse
{
    // instance variables - replace the example below with your own
    private int naoHerda;
    int herda;

    /**
     * Constructor for objects of class Superclasse
     */
    public Superclasse()
    {
        naoHerda = 20;
        herda = 10;
    }
    
    /**
     * Metodo acessador ao naoHerda
     */
    public int getNaoHerda() {
        return naoHerda;
    }
    
    /**
     * Metodo acessador ao herda
     */
    public int getHerda() {
        return herda;
    }
    
    /**
     * Metodo modificador de naoHerda
     * @param novoNaoHerda Novo valor de naoHerda
     */
    public void setNaoHerda(int novoNaoHerda) {
        naoHerda = novoNaoHerda;
    }
    
    /**
     * Metodo modificador de herda
     * @param novoHerda Novo valor de herda
     */
    public void setHerda(int novoHerda) {
        herda = novoHerda;
    }
}

A a subclasse


/**
 * Write a description of class Subclasse here.
 * 
 * @author (your name) 
 * @version (a version number or a date)
 */
public class Subclasse extends Superclasse
{
    /**
     * Constructor for objects of class Subclasse
     */
    public Subclasse()
    {
        super();
    }
    
    /**
     * Vai apresentar os valores 10 e 20 na tela
     */
    public void imprimeTodos() {
        System.out.println("super.herda = " + super.herda);
        System.out.println("herda =  " + herda);
        //System.out.println("super.naoHerda = " + super.naoHerda); // esse nao compilou, como o felipao disse
        //System.out.println("naoHerda = " + naoHerda); // esse tambem nao
        System.out.println("nao herda = " + super.getNaoHerda());
    }
    
    /**
     * Vai mudar os valores de herda e naoHerda (pelo menos vai tentar)
     */
    public void setValores(int novoNaoHerda, int novoHerda) {
        super.setNaoHerda(novoNaoHerda);    // aqui ele compila em ambos... mesmo sendo private, e possivel mudar o valor da variavel entao?
        super.setHerda(novoHerda);
    }
}

Bom… aí já tá dito né… agora é possível tanto acessar os valores e mostrar os mesmos e setar novos valores pra eles.
Tá certo e coeso isso?

Senhores,
Para responder é necessário tão somente lembrar das definições em OO para Herança:
Por herança compreendemos todos ser a capacidade que uma determinada classe possui de encapsular os membros de uma outra classe, então chamada “superclasse”. Sabemos ainda que uma relação de herança corresponde a uma relação “is a”. Ou seja: se “uma classe” “estende” uma outra, ela é “uma outra”. Se é “uma outra”, possui todos os membrpos existentes em “uma outra”, o que inclui os membros privados. Pronto! A questão está respondida!
Mas, para que não hajam dúvidas, lembremos a definição de membro privado. Que diz que um membro privado só pode ser acessado a partir da classe em que é encapsulado. Desta forma, mesmo que “uma classe” herde um membro privado de “uma outra”, não poderá acessá-lo pois este membro não foi encapsulado em "uma classe’, mas sim em “uma outra”. Caso seja necessário op acesso a estes membros privados em “uma outra” a partir de “uma classe”, definem-se seletores e modificadores públicos para estes membros em “uma outra”.

Eu li os posts desse tópico, que é muito interessante, e estou convencido de que membros privados de superclasses são herdados pelas suas subclasses. Já a visibilidade é outra coisa, eu estava confundindo herança com visibilidade.

Obrigado a todos pelas informações fornecidas!

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…


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:

class A {
    private String cpf;

    public String getCpf() {
        return this.cpf;
    }

    public void setCpf(String cpf) {
        this.cpf = cpf;
    }
}

class B extends A {
    //
}

class Teste {
    
    public static void main(String[] args) {
        B b = new B();
        b.setCpf("99.999.999-99"); // Alterando a propriedade CPF
        System.out.println(b.getCpf()); // Obtendo a propriedade CPF
    }

}

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

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

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

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).

[quote=felipealbuquerque]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:

class A {
    private String cpf;

    public String getCpf() {
        return this.cpf;
    }

    public void setCpf(String cpf) {
        this.cpf = cpf;
    }
}

class B extends A {
    //
}

class Teste {
    
    public static void main(String[] args) {
        B b = new B();
        b.setCpf("99.999.999-99"); // Alterando a propriedade CPF
        System.out.println(b.getCpf()); // Obtendo a propriedade CPF
    }

}

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

A propósito… feliz natal (antecipado) a todos![/quote]

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!

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.

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

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! :smiley:

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.

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

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… :D.

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!

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

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.

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 …