Classe abstratas vs Interfaces

Ao definir um tipo abstrato frequentemente nos deparamos com um uma escolha entre interfaces e classes abstratas eu gostaria de saber a opinião de vocês a respeito, eu acho a utilização da classe abstrata mais vantajoso
apesar de algumas situações o uso de interfaces é melhor vou colocar algumas situações que eu estou presenciando com as duas formas:

O uso de interface é útil porque qualquer classe pode implementa-la mesmo se a classe se estender há uma superclasse completamente não-relacionada
eu acho essa uma grande vantagem de usar a interface, mas se a interface tiver uns 100 métodos…?? pode causar muito stress implementar todos,
uma classe abstrata não prescisa ser inteiramente abstrada também pode conter outros métodos não abstratos isso deve deixar o processo mais rápido, mas uma classe que extende a uma classe abstrada não pode extender a outra já com interface isso pode ser feito.

A GRANDE DESVANTAGEM EM USAR INTERFACES É:
Neste caso diz respeito a compatibilidade. Se definirmos uma interface com parte de uma API pública e mais tarde adicionar um novo método á interface quebrará todas as classe que implementam a versão anterior, imaginem um sistema que 100 classe implementam a mesma interface…
isso com certeza séria estressante! Contudo se você utilizar uma classe abstrata , poderá adicionar adicionar métodos não abstratos de forma segura sem modificar métodos que extendem á essa classe abstrata.

Contudo eu acho que a utilização de uma ou de outra vai muito do projeto
as duas tem suas vantagem e desvantagens, mais no contexto geral eu acho o uso de classes abstratas mais coerente.

Não vejo isso como uma grande desvantagem.

Ate hoje, as interfaces que eu vi são muito pequenas, com no maximo 6 metodos. Se vc tiver uma interface com 100 métodos, cada classe que resolver implementar essa interface vai ter um trabalhão desgraçado.

Alem do mais, classe (abstrata ou não) vc só pode extender uma, interface vc implementa varias. Alem disso, vc pode quebrar as classes filhas alterando a classe pai de uma forma muito mais fácil do que alterando uma interface que, por ventura, alguma classe implementa.

Interfaces BEM PLANEJADAS não dão todo esse trabalho.
É interessante tentar utilizar menos herança e mais interfaces. Voce pode se dar bem DELEGANDO funcionalidades à outro objeto que simplesmente fazê-lo herdar de algum objeto.

Eu acho que as interfaces quando bem utilizadas são as melhores opções.

Minha opinião tá aqui:

Patterns - Fundamental

Deduções minhas sobre um Livro de Patterns. (Mark Grand, Patterns in Java, Volume 1)

Abraços

Acho que o desafio mesmo é utilizar os dois da melhor maneira…

As classes abstratas para implementar comportamentos típicos de suas classes filhas e interfaces para definir todo o resto que não é comum entre as classes…

Só com um bom planejamento pode-se fazer uma boa utilização dessas técnicas…

A desvantagem que você apontou para a interface também se aplica as classes abstratas. Todos os métodos publicados da classe abstrata serão também fixados, e você terá problemas sérios se altera-los.

A interface, só deve conter a parte pública. Se você está publicando métodos que não deveriam ser públicos, então está modelando incorretamente sua interface.

Eu prefiro encarar a interface como um compromisso comportamental. Por exemplo, quando um método recebe como parâmetro uma interface ele está simplesmente dizendo: “Eu espero um objeto qualquer, desde que ele se comporte dessa maneira”. Note que essa é uma relação fraca, pois objetos de tipos completamente diferente podem ter um mesmo comportamento. E um objeto pode ter mais de um comportamento. Por isso, ele pode implementar mais de uma interface.

Já as classes abstratas representam uma relação de tipos. Aquele mesmo método, se usasse uma classe abstrata diria: “Eu preciso de um objeto que seja do mesmo tipo desse outro objeto aqui”.

Isso é uma relação muitíssimo mais forte e, portanto, você poderá esperar por mais acoplamento em seu sistema. Até por isso, classes abstratas também podem conter atributos, métodos protegidos, chamar métodos das classes filhas, etc. Afinal, estamos falando de classes do mesmo tipo.

Agora vamos as vantagens da interface em relação as classes abstratas:

  1. Um objeto pode implementar mais de uma interface;

  2. O objeto pode implementar uma interface em qualquer nível da hierarquia que ele pertença. Por exemplo, Você tem 3 níveis: Animal->Mamífero->Cachorro, e a interface Farejador poderá ser implementada apenas na classe Cachorro. Isso não é possível com classes abstratas, pois cada classe só pode ter uma classe pai. Você também poderia fazer isso para classes em diferentes pontos da hierarquia, como implementar Nadador para Pato (filho de Ave) e não implementar para Galinha; e implementar para Jacaré (filho de Réptil) e não implementar para Lagartixa;

  3. Você pode fazer proxies dinâmicos com interfaces usando a classe java.lang.reflect.Proxy;

  4. É mais fácil fazer injeção de dependência em interfaces. Isso flexibiliza o sistema e facilita os testes.

A vantagem das classes abstratas é:
Você pode ter implementações default em classes abstratas;

Por isso, é muito comum um idioma combinado. Defina a interface básica que você precisa, e crie uma classe abstrata para facilitar a sua implementação. O próprio java tem exemplos disso:

  • Interface TableModel, classe AbstractTableModel
  • Interface KeyListener, classe KeyAdapter

PS: Há um tempo atrás, já houve uma discussão dessas no GUJ.

Sugiro a leitura:
http://www.guj.com.br/posts/list/51866.java