Una rapida ricerca di questo scambio di stack mostra che in generale la composizione è generalmente considerata più flessibile dell'eredità, ma come sempre dipende dal progetto ecc. E ci sono momenti in cui l'ereditarietà è la scelta migliore. Voglio fare una partita a scacchi 3D in cui ogni pezzo ha una trama, possibilmente animazioni diverse e così via. In questo esempio concreto sembra che tu possa argomentare un caso per entrambi gli approcci, sbaglio?
L'ereditarietà sarebbe simile a questa (con un costruttore appropriato, ecc.)
class BasePiece
{
virtual Squares GetValidMoveSquares() = 0;
Mesh* mesh;
// Other fields
}
class Pawn : public BasePiece
{
Squares GetValidMoveSquares() override;
}
che certamente obbedisce al principio "is-a" mentre la composizione sarebbe simile a questa
class MovementComponent
{
virtual Squares GetValidMoveSquares() = 0;
}
class PawnMovementComponent
{
Squares GetValidMoveSquares() override;
}
enum class Type
{
PAWN,
BISHOP, //etc
}
class Piece
{
MovementComponent* movementComponent;
MeshComponent* mesh;
Type type;
// Other fields
}
È più una questione di preferenze personali o un approccio è chiaramente una scelta più intelligente dell'altro qui?
EDIT: Penso di aver imparato qualcosa da ogni risposta, quindi mi sento male per averne solo una. La mia soluzione finale trarrà ispirazione da molti dei post qui (ancora lavorando su di esso). Grazie a tutti coloro che hanno avuto il tempo di rispondere.
var Pawn = new Piece(howIMove, howITake, whatILookLike)
mi sembra molto più semplice, più gestibile e più gestibile di una gerarchia ereditaria.