Por exemplo:
Digamos que eu tenha aulas A
, B
, C
. Eu tenho duas interfaces, vamos chamá-los IAnimal
e IDog
. IDog
herda de IAnimal
. A
e B
são IDog
s, enquanto C
não é, mas é um IAnimal
.
A parte importante é que IDog
não fornece funcionalidade adicional. É usado apenas para permitir A
e B
, mas não C
, ser passado como argumento para certos métodos.
Isso é uma prática ruim?
object-oriented
interfaces
Kendall Frey
fonte
fonte
IAnimal
eIDog
são terríveis nomes de tautologia!MyProject.Data.IAnimal
eMyProject.Data.Animal
são melhores queMyProject.Data.Interfaces.Animal
e #MyProject.Data.Implementations.Animal
Interface
ouImplementation
, seja em um prefixo repetitivo ou em um espaço para nome, é uma tautologia de qualquer maneira e viola o DRY.Dog
é tudo com o que você deve se preocupar.PitBull extends Dog
também não precisa de redundância de implementação, a palavraextends
me diz tudo o que preciso saber, leia o link que publiquei no meu comentário original.Respostas:
Interface que não possui nenhum membro ou tem exatamente os mesmos membros com outra interface herdada da mesma interface chamada Interface do Marcador e você a está usando como marcador.
Não é uma prática recomendada, mas a interface pode ser substituída por atributos (anotações) se o idioma que você estiver usando o suportar.
Posso dizer com confiança que não é uma prática ruim, porque eu vi o padrão "Marker Interface" de uso pesado no Orchard Project
Aqui está um exemplo do projeto Orchard.
Por favor, consulte a Interface do Marcador .
fonte
C
para um método que espera umIDog
.Kennel
classe que armazena uma lista deIDog
s.Sim, é uma prática ruim em quase todos os idiomas.
Os tipos não existem para codificar dados; eles são uma ajuda para provar que seus dados vão para onde precisam e se comportam como precisam. A única razão para subtipo é se um comportamento polimórfico muda (e nem sempre então).
Como não há digitação, o que um IDog pode fazer está implícito. Um programador pensa uma coisa, outro pensa outra e as coisas quebram. Ou as coisas que ele representa aumentam à medida que você precisa de um controle mais refinado.
[editar: esclarecimentos]
O que quero dizer é que você está fazendo alguma lógica com base na interface. Por que alguns métodos só funcionam com cães e outros com qualquer animal? Essa diferença é um contrato implícito, pois não há um membro real que forneça a diferença; nenhum dado real no sistema. A única diferença é a interface (daí o comentário 'no digitando'), e o que isso significa será diferente entre os programadores. [/editar]
Certos idiomas fornecem mecanismos de características em que isso não é muito ruim, mas tendem a se concentrar nos recursos, não no refinamento. Tenho pouca experiência com eles, por isso não posso falar com as melhores práticas lá. Em C ++ / Java / C # embora ... não é bom.
fonte
Kennel
classe que armazena uma lista deIDog
s.Eu só conheço bem C #, então não posso dizer isso para programação OO em geral, mas como um exemplo C #, se você precisar categorizar classes, as opções óbvias são interfaces, propriedade enum ou atributos personalizados. Normalmente eu escolheria a interface, não importa o que os outros pensem.
fonte
Não há nada de errado em ter uma interface que herda outra interface sem adicionar novos membros, se for esperado que todas as implementações dessa última interface possam fazer coisas úteis que algumas implementações da anterior podem não ter. De fato, é um bom padrão que o IMHO deveria ter sido usado mais em coisas como o .net Framework, especialmente porque um implementador cuja classe naturalmente satisfaria as restrições implícitas na interface mais derivada pode indicar que simplesmente implementando a interface mais derivada , sem precisar alterar nenhum código ou declaração de implementação de membro.
Por exemplo, suponha que eu tenha as interfaces:
IImmutableFoo.AsImmutable()
Espera-se que uma implementação de retorne a si mesma;IMaybeMutableFoo.AsImmutable()
seria esperado que uma implementação de classe mutável retornasse um novo objeto profundamente imutável contendo um instantâneo dos dados. Uma rotina que deseja armazenar uma captura instantânea dos dados mantidos em umIMaybeMutableFoo
pode oferecer sobrecargas:Nos casos em que o compilador não sabe que o objeto a ser armazenado é um
IImmutableFoo
, ele chamaráAsImmutable()
. A função deve retornar rapidamente se o item já estiver imutável, mas uma chamada de função através de uma interface ainda leva tempo. Se o compilador souber que o item já é umIImmutableFoo
, poderá ignorar a chamada de função desnecessária.fonte