Herança X interfaces

Estou estudando e me deparei com a seguintes duvidas!!!

Em muitos lugares se fala muito de acoplamento, com o uso de herança se tem um grande acomplamento e se recomenda utilizar em muitos casos interfaces. Estou certo do que entendi?

Entao em uma apostila tem um exemplo que é utilizado onde ContaCorrente e ContaPoupanca tem como superClasse Conta, assim alguns dos metodos que é pra ser implementado igual nas classes ContaCorrente e ContaPoupanca é implementado em Conta.

Para simular esta mesma situação utilizando interfaces é criado uma interface Conta, assim, ContaCorrente e ContaPoupanca implements Conta.

public interface Conta {

double getSaldo();
void deposita(double valor);
void retira(double valor);
void atualiza(double selic);

}

entao em ContaCorrente e ContaPoupanca somente atualiza(double selic) que é diferente nas duas classes.

Minha duvida seria há alguma maneira que deve ser feita para que nao seja necessario ter os outros metodos implementados nas duas ou tem que implementar eles nas duas?

Bem, vou tentar responder a diferença e a utilização das duas maneiras bem simples o objetivo.

Herança: É quando você deseja herdar algo que já está pronto e não deseja refazê-lo novamente. (Óbivio)

Interface: É quando você cria um Interface onde nela existe declarações de métodos,
onde à classe que for implementar-la tem que, obrigatoriamente, implementar todos os método contidos nela.

Por favor alguém corriga-me se eu estiver enganado.

Por exemplo existe uma classe chamanda Collections.sort, é uma classe que contém esse método que serve
para ordenar uma determinada lista. Mas para você passar uma classe, que você tenha criado e precisa que
os valores contidos nela sejam ordenados, para esse método é preciso que você implemente a Interface List,
porque nessa Interface terá métodos que o método Collections.sort irá utilizar dentro dele para fazer a ordenação
dessa classe (ou lista).

Espero que tenha entendido.

Até mais!

Faltou citar que herança de implementação pode ser substituída por herança de interface + composição + delegação. Ao invés de criar uma classe Conta e fazer as outras estendê-la você cria uma interface Conta e uma classe ContaImp (Imp de implementação). A classe ContaImp deve conter as implementações padrão dos métodos comuns a toda conta. Daí, a sua classe ContaCorrente deve implementar a interface Conta e manter um campo ContaImp. Por fim, a não ser que você deva fornecer uma implementação diferente para algum dos métodos da interface, você delega as chamadas de ContaCorrente para ContaImp.

Herança é uma relação É-UM, se faz sentido use herança, se vc puder use composição. Usar interfaces pode te dar um poder interessante no que diz respeito a polimorfismo.

Outra opção.

Usar interface também não significa que você tenha que abrir mão de classes abstratas. Nada impede você de criar a interface Conta e criar uma classe abstrata, chamada AbstractConta, com as implementações padrão. Como nesse caso, ContaCorrente e ContaPoupança são um abstract conta, você não perde tanto por usar herança.

O importante é que classes externas vejam como tipo externo a interface e não a classe abstrata. Que métodos que exijam uma superclasse de ContaCorrente ou ContaPoupança também usem a interface como seus parâmetros.

Assim, se um novo tipo de conta diferente surgir no seu sistema, que não se adapte bem a classe AbstractConta, você ainde poderá implementa-lo.

Veja esse texto que pode te esclarecer melhor: http://www.guj.com.br/posts/list/55387.java#290673

E ai galera! Sei que o pessoal não gosta de ressuscitar tópicos, mas, é melhor centrarlizar o
assunto do que criar um novo tópico.
Estou com a seguinte situação tenho a entidade Pessoa com seus atributos
tenho uma subclasse Funcionario que acrescenta alguns atributos
existe uma subclasse de Funcionario, Examinador que acrescenta mais atributos
e agora surgiu uma nova classe que pode ser subclasse de Funcionario e
provavelmente pode surgir mais.
A situação é a seguinte me parece necessário ter as classes/tabelas Pessoa, Funcionario e Examinador
mas as novas classes poderiam ser apenas funções/papeis(Fiscal, Porteiro etc.) de Funcionario.
Gostaria de melhorar essa estrutura e me parece que com a composição ficaria melhor, mas,
ainda não cheguei a um senso comum. Como eu aplicaria o conceito da resposta do ViniGodoy
Conta e AbstractConta?
Por isso peço a opnião de voces ViniGodoy e a galera ai.
flws

Ah sim exitem pessoas que podem acumular papéis.

Veja, você mesmo fala de papéis como um conceito bastante sólido em seu sistema. Por isso, separe os papéis da implementação da classe pessoa, como uma classe separada.
Note que, a partir do momento que uma pessoa pode acumular mais de um papel, será muitíssimo difícil levar essa relação com herança.

Aliás, sempre desconfie se a árvore de herança começar a ficar muito alta. Se começar a tender para mais de 3 níveis, é um mau cheiro, um indício de que algo pode ser errado.

Certo! Eu fiz um Enum que define todos os papeis.
Minha estrutura tem essa ordem hierarquica
agora, começando da superclasse
Pessoa (classe abstrata)
Funcionario (tem um Set)
Examinador(mais alguns atributos)
Defini um atributo do tipo Set no Funcionario, mas
me parece estranho ainda. O Examinador tem um papel
de Coordenador as vezes e é um examinador sempre isto que esta estranho.
Eu teria alguma outra forma de fazer isso?
Composição em vez de herança?

A dúvida surgiu depois que vi este link:
http://www.dsc.ufcg.edu.br/~jacques/cursos/map/html/pat/herancavscomposicao.htm
por isso não sei qual seria a melhor implementação

Link interessante, mas acho que composição lhe dá mais flexibilidade, apesar de que pela lógica do seu sistema se trata de uma herança já que um Examinador é um Funcionário e um Funcionário é uma Pessoa.

Boa Noite!
Alguns detalhes que eu não disse é que o sistema é para expedição de CNH.
Um examinador tera que ser cadastrado como candidato em alguns casos. Tanto examinador
quanto candidato extendem de funcionario:
Pessoa <- Funcionario <- Examinador
Pessoa <- Funcionario <- Candidato
Um candidato é um funcionario, como candidato ele faria a prova, como funcionario ele poderia ser fiscal por exemplo.
Um candidato pode ser um examinador;
um examinador pode ser um candidato e é um funcionario, como funcionario ele pode exercer um papel de coordenador.
Um dos problemas esta em transformar o candidato num examinador e vice versa.
Outro ocorre quando um examinador deixa de ser examinador, nesse momento
os dados deveriam ser removidos ou apenas desativados da tabela examinador, mas,
mantidos na tabela funcionario, pois ainda seriam coordenador.
Não me parece bem estruturado.
Este é o cenario atual queria melhora-lo? Alguem tem mais alguma opnião?
ViniGodoy, Paulo Silveira e toda a galera ai…

Eu não criaria herança entre os papéis. Faça uma classe de papel separada e crie uma lista de papéis por usuário. Além de mais simples concentualmente, te dará muito mais flexibilidade.

ViniGodoy

“Faltou citar que herança de implementação pode ser substituída por herança de interface + composição + delegação.”

Boa noite pessoal, desculpa eu ressuscitar o tópico, ainda sou novato, e estou começando a estudar padrões de projeto para fazer diagramas de classes, e estou com uma dúvida. Aprendi que devemos preferir COMPOSIÇÃO e INTERFACES a herança e classes abstratas.

Ok, mas é possível usar Composição com Interfaces ?? Ou seja, estender (ou melhor implementar) a interface APENAS com Composição?

A maioria dos exemplos mostra algumas classes Herdando da Interface e a Interface fazendo algum tipo de ligação com outra classe.
Teria algum exemplo simples prático para eu compreender melhor ??

Achei este exemplo só para demonstrar a minha dúvida, que não é sobre o padrão Strategy, mas saber se seria possível ou até uma boa pratica trocar aquela Herança por Composição ??? Ou ta tudo errado mesmo isso que to pensando …

Ainda não consegui entender isso : “substituída por herança de interface + composição + delegação.”

Sei que é o correto, mas não conseguir implementar …

Implementação de interface não é herança. Parece herança, mas o nome dessa relação é “realização” (uma tradução de realization).

Mas a saída é gerlamente essa mesmo. Separar o que está te forçando a fazer herança num componente, descrito por uma interface, e então criar subclasses para esse componente em separado. É melhor ter pequenas hierarquias interligadas por composição, do que uma única hierarquia gigante.