Uma classe deve saber sobre suas subclasses? Uma classe deve fazer algo específico para uma determinada subclasse, por exemplo?
Meus instintos me dizem que esse é um projeto ruim, parece algum tipo de antipadrão.
Uma classe deve saber sobre suas subclasses? Uma classe deve fazer algo específico para uma determinada subclasse, por exemplo?
Meus instintos me dizem que esse é um projeto ruim, parece algum tipo de antipadrão.
Respostas:
A resposta implícita no conceito de classe é "não".
Qualquer ação, dado ou relação que você esteja manipulando faz parte de todas as subclasses - então ele deve ser tratado na superclasse sem verificar o tipo real. Ou aplica-se apenas a algumas subclasses - então você teria que executar verificações de tipo de tempo de execução para fazer a coisa certa, a superclasse teria que ser alterada sempre que alguém herda dela (ou pode fazer silenciosamente a coisa errada), alterações nas classes derivadas podem quebrar a superclasse inalterada etc.
Em suma, você obtém uma série de consequências ruins que geralmente são ruins o suficiente para rejeitar tais soluções imediatamente. Se várias de suas subclasses fazem a mesma coisa e você deseja evitar a duplicação de código (praticamente sempre uma coisa boa), uma solução melhor é introduzir uma classe de nível médio a partir da qual todas essas subclasses podem herdar o código.
fonte
Não apenas não deveria saber, como simplesmente não pode ! Normalmente, uma classe pode ser estendida a qualquer hora, em qualquer lugar. Pode ser estendido por classes que nem existiam quando foram escritas.
Alguns idiomas permitem que as classes extensivas sejam controladas pela superclasse. No Scala, uma classe pode ser marcada como
sealed
, o que significa que só pode ser estendida por outras classes na mesma unidade de compilação (arquivo de origem). No entanto, a menos que essas subclasses também sejamsealed
oufinal
, as subclasses poderão ser estendidas por outras classes.No Scala, isso é usado para modelar tipos de dados algébricos fechados, de modo que o
List
tipo canônico de Haskell :pode ser modelado no Scala assim:
E você pode garantir que apenas essas duas sub- "classes" existam porque
List
sãosealed
e, portanto, não podem ser estendidas fora do arquivo,Cons
sãofinal
e, portanto, não podem ser estendidas de todo eNil
é umaobject
que não pode ser estendida de qualquer maneira.Mas este é um caso de uso específico (modelagem de tipos de dados algébricos por herança) e, mesmo nesse caso, a superclasse não conhece realmente suas subclasses. É mais uma garantia para o usuário do
List
tipo que, se ele fizer uma discriminação de casosNil
eCons
, não haverá outra alternativa aparecendo nas suas costas.fonte
abstract internal
membro.A resposta simples é não.
Torna o código frágil e anula dois princípios básicos da programação orientada a objetos.
fonte
Sim as vezes. Por exemplo, quando existe um número limitado de subclasses. Um padrão de visitante é uma ilustração da utilidade dessa abordagem.
Exemplo: todos os nós da árvore de sintaxe abstrata (AST) de alguma gramática bem definida podem ser herdados de uma única
Node
classe implementando um padrão de visitante para manipular todos os tipos de nós.fonte
Node
classe base , é claro, não contém nenhuma referência direta a suas subclasses. Mas ele contém umaccept
método com umVisitor
parâmetro EVisitor
contém umvisit
método para cada subclasse. Portanto, apesar deNode
não ter referências diretas a suas subclasses, ele "sabe" indiretamente sobre elas, através daVisitor
interface. Todos eles se uniram através dele.Se eu escrever um componente para uma empresa e mais tarde, depois que eu for embora, alguém o estenderá para seus próprios propósitos, devo ser informado sobre isso?
Não!
O mesmo com as classes. Confie nos seus instintos.
fonte