Private x Protected [Hierarquia]

9 respostas
DHS

Boa Noite Pessoal, queria nesse tópico levantar essa questão: declarar os atributos da super classe como protected ou declará-los como private e oferecer sets e gets para manipulá-los. Iniciei o estudo de Java, e ao estudar hierarquia percebi essa aparente contradição, ou dualidade em relação a utilização dessas duas possíveis formas de encapsulamento.
Tenho utilizado Java Como Programar, 6º Edição, Deitel.
E nele, o autor apresenta ambas possibilidades, mas destaca nas páginas 318 e 319, que utilizar os atributos private na superclasse, e oferecer métodos set e get public para esses atributos caracteriza uma melhor engenharia de software, pois dessa forma as variáveis mantêm-se ocultas as subclasses.
Ele faz a ressalva que a chamada de métodos set e get controposto ao acesso direto dos atributos acarretam em uma perda de performance. Todavia é justificável perante à prática da boa engenharia de software, e por conseqüência a segurança que ganha-se utilizando atributos privates.
Gostaria de saber dos mais experientes, qual forma mais utilizada e qual a posição de vocês em relação essa duas possibilidades.

9 Respostas

rogelgarcia

Eu geralmente uso protected…

Mas mais por uma questão de gosto mesmo…

Aliás… geralmente eu deixo default (fica mais limpo o código… hehe)

rogelgarcia

Mas rola uma certa forçaçao de barra nessas boas praticas as vezes… O cara quer fazer tão certinho… que o programa fica cheio de coisas desnecessárias (to falando de maneira geral … nao só nesse caso)

Nunca vi um problema de ter um atributo protected e acessar ele diretamente da subclasse…

Mas já vi atributos private sem getter e setter… aí foi osso… :smiley:

Das vezes que vi alguém colocando código no getter e no setter além do padrão… foi gambiarra… heheheh

ViniGodoy

Eu uso private e gets e sets protected. Se não precisa ser public, não será public.

Não existe perda de performance em usar gets e sets. A virtual machine é capaz de fazer inlining dos métodos.

aeciovc

traduzindo??

eu sempre uso private!! nunca uso protected!

Trebloc

ViniGodoy:
Eu uso private e gets e sets protected. Se não precisa ser public, não será public.

Não existe perda de performance em usar gets e sets. A virtual machine é capaz de fazer inlining dos métodos.

Digo o mesmo. :roll:

Na verdade, só acho protected necessário quando o método deveria ser private, mas pode haver necessidade de alguma sbuclasse sobrescrevê-lo (e ele não pode ser público, muito menos default).

Já campos, pelo menos no tempo que trabalho com Java nunca tive necessidade alguma de tê-los com visibilidade protected (apesar de várias classes do Java o utilizarem).

rmendes08

A questão é bastante simples é resume-se a aplicar a pedra fundamental da POO: separar claramente implementação de interface. Assim, os atributos de uma classe somente devem ser public se o get/set fazer parte da interface, ou seja, se o atributo representa uma propriedade no contrato de operação do objeto. Para fazer essa separação devemos usar interfaces, composição e delegação, que à primeira vista parece mais difícil que herança. Mas não o é. Isso porque quando projetamos uma classe para ser herdada devemos projetar duas interfaces: uma para quem usa e outra para quem estende. Resumindo:

public - interface para quem USA a classe

protected - interface para ESTENDE a classe

private - implementação

Assim, fica bem mais simples decidir se um membro deve ser private ou protected: se ele diz respeito à implementação da classe ele deve ser private, se ele deve ser exposto como parte do contrato entre a superclasse e a subclasse então ele deve ser protected.

ViniGodoy
aeciovc:
traduzindo??

Inline é a capacidade que o compilador tem de eliminar completamente uma chamada de um método, quando ele vê quei isso é possível.

Veja, sem inline uma instrução como:

public class Y {
    int value;

    public int getValue() { return value; }
}

int x = y.getValue();

faria:

1. Guardaria o valor do ponteiro de código na pilha;
2. Obteria o endereço de getValue();
3. Entraria no getValue() e obteria o valor de value;
4. Desempilharia o endereço do método antigo e mudaria o código para lá.
5. Atribuiria o valor de y para x.

Toda essa opção é fantasticamente rápida, entretanto, geralmente desnecessária. O compilador, quando nota que um método simplesmente retorna um valor, transforma o código:
int x = y.getValue();
Em:
int x = y.value;

Ou seja, a chamada de método não é feita e o atributo é diretamente obtido, como se fosse público.

O compilador também faz inline de métodos que chamam métodos. Por exemplo, se vc tiver a seguinte situação:
public class A {
    private B b = new B();

    public void fazAlgo() {
          b.fazAlgo();
    }
}

public class B {
    private C c = new C();

    public void fazAlgo() {
          c.fazAlgo();
    }
}

public class C {

    public void fazAlgo() {
          //Faz qualquer coisa.
    }
}

Uma chamada a A.do() será substituida pelo compilado a uma chamada à c.Do(), direta, sem a necessidade de alocar pilha nos passos intermediários.

aeciovc

deu uma aula Vini! não conhecia isso!! vlw!

[size=9]Aécio Costa
Desenvolvedor Delphi e Java
Twitter: http://twitter.com/aeciovc[/size]

ViniGodoy

Dá uma lida:
http://www.compileroptimizations.com

Criado 25 de março de 2010
Ultima resposta 26 de mar. de 2010
Respostas 9
Participantes 6