fundo
Aqui está o problema real em que estou trabalhando: quero uma maneira de representar cartas no jogo de cartas Magic: The Gathering . A maioria das cartas do jogo são de aparência normal, mas algumas são divididas em duas partes, cada uma com seu próprio nome. Cada metade desses cartões de duas partes é tratada como um cartão em si. Portanto, para maior clareza, usarei Cardapenas para me referir a algo que é um cartão comum ou metade de um cartão de duas partes (em outras palavras, algo com apenas um nome).

Portanto, temos um tipo base, cartão. O objetivo desses objetos é realmente apenas manter as propriedades do cartão. Eles realmente não fazem nada sozinhos.
interface Card {
String name();
String text();
// etc
}
Existem duas subclasses de Cardque estou chamando PartialCard(metade de um cartão de duas partes) e WholeCard(um cartão comum). PartialCardpossui dois métodos adicionais: PartialCard otherPart()e boolean isFirstPart().
Representantes
Se eu tiver um deck, ele deve ser composto por WholeCards, não Cards, como Cardpoderia ser um PartialCard, e isso não faria sentido. Então, eu quero um objeto que represente um "cartão físico", ou seja, algo que possa representar um WholeCardou dois PartialCards. Estou provisoriamente chamando este tipo Representative, e Cardteria o método getRepresentative(). A Representativeforneceria quase nenhuma informação direta no (s) cartão (s) que representa, apenas apontaria para ele / eles. Agora, minha idéia brilhante / louca / burra (você decide) é que o WholeCard herda de ambos Card e Representative. Afinal, são cartões que se representam! WholeCards poderia implementar getRepresentativecomo return this;.
Quanto a PartialCards, eles não se representam, mas eles têm um externo Representativeque não é um Card, mas fornecem métodos para acessar os dois PartialCards.
Eu acho que essa hierarquia de tipos faz sentido, mas é complicado. Se pensarmos em Cards como "cartões conceituais" Representativees como "cartões físicos", bem, a maioria dos cartões é ambos! Eu acho que você poderia argumentar que os cartões físicos contêm de fato cartões conceituais e que eles não são a mesma coisa , mas eu argumentaria que eles são.
Necessidade de fundição
Como PartialCards e WholeCardssão ambos Cards, e geralmente não há uma boa razão para separá-los, normalmente eu apenas estaria trabalhando Collection<Card>. Então, às vezes, eu precisaria converter PartialCards para acessar seus métodos adicionais. No momento, estou usando o sistema descrito aqui porque realmente não gosto de elencos explícitos. E como Card, Representativeprecisaria ser convertido para a WholeCardou Compositepara acessar os Cards reais que eles representam.
Então, apenas para resumo:
- Tipo de base
Representative - Tipo de base
Card - Tipo
WholeCard extends Card, Representative(não é necessário acesso, ele representa a si próprio) - Tipo
PartialCard extends Card(dá acesso a outra parte) - Tipo
Composite extends Representative(dá acesso às duas partes)
Isso é loucura? Acho que faz muito sentido, mas sinceramente não tenho certeza.