Pergunta

Comecei com uma interface genérica chamada ilogin. As interfaces exigem que você implemente duas propriedades: UserID e senha. Eu tenho muitas classes do tipo login que implementam essa interface. À medida que meu projeto crescia e crescia, achei que muitas classes repetiam o ID do usuário e o código de senha. Agora eu decido que preciso de uma classe de login base.

É apropriado criar uma classe de login de base abstrata que implementa a interface ilogina e tenha todas as minhas classes concretas apenas herdem da classe abstrata e substituem quando necessário? Originalmente, eu estava pensando que não haveria problema com isso. Então comecei a pensar que o ilogin provavelmente não foi desnecessário porque provavelmente só será implementado pela minha classe abstrata.

Existe um benefício em manter a classe abstrata e a interface?

Obrigado!

Foi útil?

Solução

Definitivamente. Vamos pensar em um exemplo concreto.

Digamos que temos uma aula abstrata Animal. Digamos, fazemos algumas subclasses Cat, Dog, Mosquito, e Eagle. Podemos implementar seu Eat(), Breathe(), Sleep() Métodos da classe abstrata Animal.

Até agora tudo bem. Agora, digamos que queremos ter o Fly() Método para o Mosquito e Eagle Aulas. Como esses dois organismos não são realmente bem relacionados (um é um pássaro, outro é um inseto), não seria fácil criar um ancestral comum para os dois que podemos ter como classe abstrata. Isso seria melhor implementado por uma interface IFly.

o IFly A interface pode ter um Fly() método a ser implementado. Ambos Mosquito e Eagle Classes podem ser subclasses da classe abstrata Animal e implementar a interface IFly e ser capaz de Eat(), Breathe(), Sleep() e Fly() sem ter algum tipo de relação antiga estranha entre as duas classes.

Outras dicas

Normalmente codificamos as classes abstratas quando faz sentido e implemento (e crio em uma montagem/biblioteca de contratos externos uma interface em todas inversão de controle Quando necessário (que quase sempre é zombador). Isso se tornou uma segunda natureza para mim.

Absolutamente. A interface é sempre o caminho correto a seguir-essa maneira de qualquer coisa pode implementá-la (incluindo algo que já tem um pai).

A classe abstrata tende a fazê -lo para que você não precise reimplementar algumas partes dessa funcionalidade. O swing usa um pouco, eles terão uma interface e, em seguida, uma implementação padrão para você substituir apenas um dos 5 métodos ou pode cuidar de adicionar ouvintes para você, mas você não precisa usar essa classe base se você não quero.

Se sua classe abstrata é a Classe que jamais implementará a interface, então você sempre pode verificar as instâncias da classe abstrata, não precisa da interface. Mas se você deseja ser compatível com o futuro com novas classes ainda não escritas, que não estenderão a classe abstrata, mas poderão usar a interface, continue usando a interface agora.

Eu concordo com o CFEDUKE. Eu sempre começo com interfaces e, no passado, usava classes abstratas que implementam interfaces e fornecem funcionalidade básica para promover a reutilização do código entre as classes que herdam da classe abstrata. Mocking e COI dependem de uma interface, por esse motivo, eu usaria interfaces em meus designs.

Se a classe abstrata tem funcionalidade, é aconselhável mantê -la. Mas se contiver apenas métodos abstratos e não campos. Não vejo utilidade para manter os dois.

Editar: Eu trabalho em código legado com muitas classes abstratas. Se alguma vez eu tiver tempo, adicionarei as interfaces (e possivelmente removerá os resumos vazios). Porque trabalhar com interfaces aprimora muito as possibilidades. E eles honram seu nome definindo exatamente a interface.

Sua interface define o contrato que deve ser cumprido para que o objeto seja aceito; Sua classe abstrata define o contrato que deve ser cumprido e define alguns detalhes específicos da implementação.

Pense dessa maneira; Se você acha que é possível que alguém queira cumprir esse contrato de uma maneira diferente da maneira como a classe abstrata esboça (digamos, com uma implementação diferente do tipo Datatype de Backing), você deve ter a interface e a classe abstrata que implementa isso.

Quase não há despesas gerais em ter a classe abstrata e a interface; Seu risco com essa abordagem envolve principalmente um codificador posterior se deparar com a interface, sem perceber que há uma classe abstrata que implementa a interface e criando uma implementação inteira do zero, onde não precisa estar. Eu diria que isso poderia ser contado especificando em sua documentação da interface que existe uma implementação "padrão" da interface em sua classe abstrata; Embora alguns padrões de codificação possam desaprovar essa prática, não vejo problemas reais com ela.

Eu sempre aconselharia que você use interfaces. As classes abstratas têm a vantagem que você pode adicionar na funcionalidade padrão, mas exigir que um usuário use sua herança única seja bastante agressiva.

As bibliotecas da Microsoft Class favorecem as classes abstratas sobre as interfaces em vários casos, porque lhes permite modificar a classe subjacente. Adicionar um método a uma classe abstrata raramente quebra alguém que herda dela. Adicionar um método a uma interface sempre quebra seus implementadores. No entanto, isso fornece uma das melhores razões para o uso de interfaces: a terrível possibilidade de a Microsoft já ter usado sua herança.

Eu sugeriria, no entanto, que, no seu caso específico, você pode revisitar o padrão de design que está usando. Parece incomum ter muitas classes "do tipo logon".

Eu acho que um benefício de manter a interface seria a capacidade de futuras classes de implementar várias interfaces, enquanto uma classe só pode herdar de uma classe abstrata.

Você pode estender a funcionalidade das subclasses, criando uma nova interface com um conjunto diferente de métodos.

Supondo que você esteja perguntando especificamente quando a interface e a classe abstrata têm assinaturas idênticas ...

... (se os membros da interface forem diferentes dos membros da classe abstrata, é claro que a resposta é sim, pode haver uma necessidade de ambos)

... mas assumindo que os membros são idênticos, então a única razão pela qual posso pensar em ambos é se você está codificando em um sistema que não permite a herança múltipla de implementação, existem duas classes em seu sistema que precisam ser polimorficamente semelhantes , mas deve herdar de diferentes classes base ...

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