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:
interface IMaybeMutableFoo {
Bar Thing {get; set;} // E outras propriedades também
bool IsMutable;
IImmutableFoo AsImmutable ();
}
interface IImmutableFoo: IMaybeMutableFoo {};
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 um IMaybeMutableFoo
pode oferecer sobrecargas:
public void StoreData (IImmutableFoo ThingToStore)
{
// Armazenar a referência será suficiente, pois ThingToStore é conhecido por ser imutável
}
publicDados públicos StoreData (IMaybeMutableFoo ThingToStore)
{
StoreData (ThingToStore.AsImmutable ()); // Chame a sobrecarga mais específica
}
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á é um IImmutableFoo
, poderá ignorar a chamada de função desnecessária.
IAnimal
eIDog
são terríveis nomes de tautologia!