Ambas son dos maneras de reutilizar código para crear nuevas clases
Herencia
Permite que una subclase herede propiedades y métodos de su superclase o clase base. Facilita la reutilización de código y creación de relaciones jerárquicas entre clases.
Sin embargo puede llevar a estructuras de clases rígidas y complejas, y a problemas de acoplamiento.
Composición
En lugar de heredad de una clase base, la clase se “compone” de otras clases incluyendo instancias de otras clases como campos.
Esto promueve un diseño más modular y flexible ya que permite cambiar el comportamiento en tiempo de ejecución.
Depende del problema específico pero la composición suele ser preferida por su flexibilidad y capacidad para evitar problemas comunes de herencia.
Ejemplo
Herencia
public class Animal
{
public void Comer() => Console.WriteLine("Este animal come");
}
public class Perro : Animal
{
public void Ladrar() => Console.WriteLine("Este perro ladra");
}
Composición
public class Animal
{
public void Comer() => Console.WriteLine("Este animal come");
}
public class Perro
{
private Animal animalComponent = new Animal();
public void Comer()
{
animalComponent.Comer(); // uso de composicion delegando el metodo en Animal
}
public void Ladrar() => Console.WriteLine("Este perro ladra");
}