Pergunta

Eu estou lidando com uma grande base de código que tem um monte de aulas e um monte de métodos abstratos sobre essas classes. Estou interessado em opiniões dos povos sobre o que devo fazer na seguinte situação.

Se eu tiver uma classe Parent-A com um método abstrato. Haverá apenas 2 crianças. Se implementos Child-B AbstractMethodA mas Child-B não como ele não se aplicam.

Devo

  1. Remova a palavra-chave abstract de pai e use dinâmica virtual ou?
  2. Fornecer uma implementação vazia do método.
  3. Fornecer uma implementação que gera um erro se for chamado.
  4. Ignorar o aviso.

Edit: Obrigado por todas as respostas. Ele confirmou minha suspeita de que isso não deve acontecer. Após uma investigação mais aprofundada despeja os métodos não foram utilizados em tudo para que eu tenha removido-los totalmente.

Foi útil?

Solução

Se AbstractMethodA não se aplica a Child-B, então Child-B não deve ser herdada de pai-A.

Ou para levar o contrapositiva, se herda Child-B de Parent-A, e AbstractMethodA não se aplica à criança, então não deve ser no pai também.

Ao colocar um método em Parent-A, você está dizendo que o método se aplica a Parent-A e todos os seus filhos. Isso é o que a herança através , e se você usá-lo para significar algo diferente, você vai acabar em uma disputa séria com seu compilador.

[Edit - que disse, a resposta de Mladen Prajdic é bom se o método se aplica, mas não deve fazer nada para uma ou mais das classes envolvidas. Um método que não faz nada, não é IMO a mesma coisa que um método que não é aplicável, mas talvez nós não queremos dizer a mesma coisa, "não se aplica"]

Outra técnica é implementar o método de Child-B de qualquer maneira, mas têm que fazer algo drástico como falha sempre retornando, ou lançar uma exceção, ou algo assim. Ele funciona, mas deve ser considerado como um pouco de um bodge em vez de um design limpo, uma vez que significa que os chamadores precisa saber que a coisa que eles têm que eles estão tratando como Pai-A é realmente uma criança-B e, portanto, não deve chamar AbstractMethodA. Basicamente você descartado polimorfismo, que é o principal benefício da herança OO. Pessoalmente eu prefiro fazê-lo desta maneira sobre ter uma implementação de lançando exceção na classe base, porque, então, uma classe filha não pode "acidentalmente" se comportar mal por "esquecer" para implementar o método em tudo. Ele tem de implementá-lo, e se ele implementa-se não funcionar, então fá-lo explicitamente. A má situação deve ser barulhento.

Outras dicas

Se a implementação em descendentes não é obrigatório, então você deve ir para 1 + 2 (ou seja, esvaziar método virtual no ancestral)

Eu acho que, em geral, você não deve herdar da classe abstrata, se você é incapaz de implementar todos os métodos abstratos, em primeiro lugar, mas eu entendo que existem algumas situações onde ainda faz senseto fazer isso (consulte a classe Stream e suas implementações).

Eu acho que você deve apenas criar implementações destes métodos abstratos que lançam um NotImplementedException.

Você também pode tentar usar ObsoleteAttribute para que chamar esse método particular seria um erro de tempo de compilação (no topo da jogando NotImplementedException é claro). Note-se que ObsoleteAttribute não é bem feito para ser usado para isso, mas eu acho que se você usar uma mensagem de erro significativo com comentários, está tudo bem.

exemplo de código obrigatório:

[Obsolete("This class does not implement this method", true)]
public override string MyReallyImportantMethod()
{
    throw new NotImplementedException("This class does not implement this method.");
}

torná-lo virtual vazio na classe base e substituí-lo em crianças.

Você pode usar interfaces. Então Criança-A e Child-B pode implementar os dois métodos diferentes e ainda herdar de Parent-A. Interfaces funcionam como métodos abstratos em que eles forçam a classe de implementá-las.

Se algumas subclasses (B1, B2, ...) de A são usadas para um subconjunto diferente de seus métodos do que outros (C1, C2, ...), pode-se dizer que A pode ser dividido em B e C .

Eu não sei Delphi muito bem (não em todos :)), mas eu pensei que, assim como por exemplo em Java e COM, uma classe pode 'implementar' múltiplas interfaces. Em C ++ isso só pode ser alcançado por multiplicar herdar classes abstratas.

Mais concreto:. Gostaria de criar duas classes abstratas (com métodos abstratos), e alterar a árvore de herança

Se isso não for possível, uma solução alternativa poderia ser um "adaptador": uma classe intermediária A_nonB_ com todos os métodos B implementado vazio (e produzindo um aviso em chamá-los), e A_nonC_. Em seguida, altere a árvore de herança para resolver seu problema:. B1, B2, ... herdarão A_nonC_ e C1, C2, ... herdarão A_NonB _

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