Pergunta

Esta pergunta me foi feita e estou francamente perplexo:

Em vez de escrever métodos abstratos, poderíamos tentar falsificá-los com exceções, como esta:

public int someMethod(int someparameter) {
    throws new RuntimeException("unimplemented");
}

Qual seria o propósito de fazer isso e alguém pode fornecer um exemplo de código para um método abstrato que o acima está tentando falsificar?Qualquer ajuda é muito apreciada.Obrigado.

Foi útil?

Solução

Posso pensar em um caso de uso (possivelmente) válido:Você tem uma classe abstrata e várias outras classes em todo o seu projeto que a estenderam.(Ou a classe abstrata está em uma biblioteca de código aberto, então você não tem ideia de quais outras classes em todo o universo podem ser estendidas a partir dela.) Agora, você descobre que é útil adicionar novos métodos abstratos a esta classe.Mas se você adicionar abstract métodos para a classe, isso quebra todas as outras classes que já a estenderam, porque essas classes precisam ser alteradas para conter a substituição dos novos métodos.Então posso ver como, em alguns casos, pode ser considerado mais viável adicioná-los como métodos não abstratos e fazer com que eles lancem exceções apenas no caso de um novo a classe que o estende usa os novos métodos, mas se esquece de escrever um método de substituição.Não será detectado em tempo de compilação, mas pelo menos poderá ser detectado durante o teste.

Não tenho certeza de quão legítimo é esse motivo, pois também é possível definir uma nova classe abstrata NewImprovedWhatever que estende o antigo, para conter os novos métodos.No entanto, isso pode representar seus próprios desafios de manutenção.Eu não tenho certeza.

Notei que Java define uma classe abstrata java.net.SocketImpl, que contém dois métodos não abstratos, shutdownInput() e shutdownOutput(), cuja implementação padrão é lançar uma exceção:

protected void shutdownInput() throws IOException {
  throw new IOException("Method not implemented!");
}

Os comentários indicam que eles foram adicionados em 1.3, então talvez seja exatamente por isso que foi feito dessa maneira, ou seja,não exigir modificação de outras classes que já estendiam SocketImpl.Mas não tenho certeza.

De qualquer forma, um design como esse certamente seria um código muito ruim, se a classe fosse projetada dessa forma do zero.Mas os bons conceitos OO que aprendemos em aula nem sempre são tão bons na prática quando o código existente precisa ser modificado.

Outras dicas

Eu às vezes joguei UnsupportedOperationException de um método cuja funcionalidade ainda não foi implementada.(Há também um NotImplementedException no Apache Commons que é uma subclasse de UnsupportedOperationException.) Isso sempre foi concebido como um espaço reservado e uma mensagem para outras pessoas que usam a classe ou serviço relacionado de que o método ainda não está completo.No entanto, esse código nunca chegou à produção.

O objetivo de fazer isso seria escrever propositalmente CÓDIGO RUIM.
Se alguém quiser confundir seus leitores e quiser que eles sintam a agonia de ler seu código, então esse código será escrito.
Também mostra falta de habilidades de design no código.
Uma API mal escrita terá esse código.
Não faça isso.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top