Preguntas sobre Herencia y Composición

# Pregunta Ejemplo en Java Ejemplo en Python Ejemplo en C# Ejemplo en TypeScript
1 ¿Qué es la herencia en programación orientada a objetos? class Animal {
  void hacerSonido() {
    System.out.println("Sonido de animal");
  }
}
class Perro extends Animal {
  void hacerSonido() {
    System.out.println("Ladrido");
  }
}
class Animal:
  def hacer_sonido(self):
    print("Sonido de animal")
class Perro(Animal):
  def hacer_sonido(self):
    print("Ladrido")
class Animal {
  public void HacerSonido() {
    Console.WriteLine("Sonido de animal");
  }
}
class Perro : Animal {
  public void HacerSonido() {
    Console.WriteLine("Ladrido");
  }
}
class Animal {
  hacerSonido(): void {
    console.log("Sonido de animal");
  }
}
class Perro extends Animal {
  hacerSonido(): void {
    console.log("Ladrido");
  }
}
2 ¿Qué es la composición en programación orientada a objetos? class Motor {
  void encender() {
    System.out.println("Motor encendido");
  }
}
class Coche {
  private Motor motor = new Motor();
  void arrancar() {
    motor.encender();
  }
}
class Motor:
  def encender(self):
    print("Motor encendido")
class Coche:
  def __init__(self):
    self.motor = Motor()
  def arrancar(self):
    self.motor.encender()
class Motor {
  public void Encender() {
    Console.WriteLine("Motor encendido");
  }
}
class Coche {
  private Motor motor = new Motor();
  public void Arrancar() {
    motor.Encender();
  }
}
class Motor {
  encender(): void {
    console.log("Motor encendido");
  }
}
class Coche {
  private motor = new Motor();
  arrancar(): void {
    this.motor.encender();
  }
}
3 ¿Cuál es la principal diferencia entre herencia y composición? // Herencia:
class Perro extends Animal { }

// Composición:
class Coche {
  private Motor motor = new Motor();
}
# Herencia:
class Perro(Animal):

# Composición:
class Coche:
  def __init__(self):
    self.motor = Motor()
// Herencia:
class Perro : Animal { }

// Composición:
class Coche {
  private Motor motor = new Motor();
}
// Herencia:
class Perro extends Animal { }

// Composición:
class Coche {
  private motor = new Motor();
}
4 ¿Cuándo deberías utilizar herencia en lugar de composición? class Vehiculo {
  void moverse() {
    System.out.println("El vehículo se mueve");
  }
}
class Coche extends Vehiculo {
  void moverse() {
    System.out.println("El coche se mueve");
  }
}
class Vehiculo:
  def moverse(self):
    print("El vehículo se mueve")
class Coche(Vehiculo):
  def moverse(self):
    print("El coche se mueve")
class Vehiculo {
  public void Moverse() {
    Console.WriteLine("El vehículo se mueve");
  }
}
class Coche : Vehiculo {
  public void Moverse() {
    Console.WriteLine("El coche se mueve");
  }
}
class Vehiculo {
  moverse(): void {
    console.log("El vehículo se mueve");
  }
}
class Coche extends Vehiculo {
  moverse(): void {
    console.log("El coche se mueve");
  }
}
5 ¿Cuándo deberías utilizar composición en lugar de herencia? class Motor {
  void encender() {
    System.out.println("Motor encendido");
  }
}
class Coche {
  private Motor motor = new Motor();
  void arrancar() {
    motor.encender();
  }
}
class Motor:
  def encender(self):
    print("Motor encendido")
class Coche:
  def __init__(self):
    self.motor = Motor()
  def arrancar(self):
    self.motor.encender()
class Motor {
  public void Encender() {
    Console.WriteLine("Motor encendido");
  }
}
class Coche {
  private Motor motor = new Motor();
  public void Arrancar() {
    motor.Encender();
  }
}
class Motor {
  encender(): void {
    console.log("Motor encendido");
  }
}
class Coche {
  private motor = new Motor();
  arrancar(): void {
    this.motor.encender();
  }
}
6 ¿Cómo puedes evitar el problema de la herencia múltiple? // Usar interfaces para evitar la herencia múltiple
interface IVolador {
  void volar();
}
class Pajaro implements IVolador {
  public void volar() {
    System.out.println("El pájaro vuela");
  }
}
# Usar interfaces para evitar la herencia múltiple
class Volador:
  def volar(self):
    print("El pájaro vuela")
class Pajaro(Volador):
  pass
// Usar interfaces para evitar la herencia múltiple
interface IVolador {
  void Volar();
}
class Pajaro : IVolador {
  public void Volar() {
    Console.WriteLine("El pájaro vuela");
  }
}
// Usar interfaces para evitar la herencia múltiple
interface Volador {
  volar(): void;
}
class Pajaro implements Volador {
  volar(): void {
    console.log("El pájaro vuela");
  }
}
7 ¿Qué ventajas ofrece la herencia sobre la composición? // Ventajas de la herencia:
// Reutilización de código
class Animal {
  void comer() {
    System.out.println("El animal come");
  }
}
class Perro extends Animal { }
# Ventajas de la herencia:
# Reutilización de código
class Animal:
  def comer(self):
    print("El animal come")
class Perro(Animal):
  pass
// Ventajas de la herencia:
// Reutilización de código
class Animal {
  public void Comer() {
    Console.WriteLine("El animal come");
  }
}
class Perro : Animal { }
// Ventajas de la herencia:
// Reutilización de código
class Animal {
  comer(): void {
    console.log("El animal come");
  }
}
class Perro extends Animal { }
8 ¿Qué desventajas puede tener la herencia? // Desventajas de la herencia:
// Dependencia entre clases
class Animal {
  void comer() {
    System.out.println("El animal come");
  }
}
class Perro extends Animal {
  void comer() {
    System.out.println("El perro come");
  }
}
# Desventajas de la herencia:
# Dependencia entre clases
class Animal:
  def comer(self):
    print("El animal come")
class Perro(Animal):
  def comer(self):
    print("El perro come")
// Desventajas de la herencia:
// Dependencia entre clases
class Animal {
  public void Comer() {
    Console.WriteLine("El animal come");
  }
}
class Perro : Animal {
  public void Comer() {
    Console.WriteLine("El perro come");
  }
}
// Desventajas de la herencia:
// Dependencia entre clases
class Animal {
  comer(): void {
    console.log("El animal come");
  }
}
class Perro extends Animal {
  comer(): void {
    console.log("El perro come");
  }
}
9 ¿Qué es el principio de sustitución de Liskov? // Principio de sustitución de Liskov:
// Las clases derivadas deben ser sustituibles por sus clases base
class Cuadrado {
  private int lado;
  void setLado(int lado) {
    this.lado = lado;
  }
  int getLado() {
    return lado;
  }
}
class Rectangulo : Cuadrado {
  private int ancho;
  void setAncho(int ancho) {
    this.ancho = ancho;
  }
}
# Principio de sustitución de Liskov:
# Las clases derivadas deben ser sustituidas por sus clases base
class Cuadrado:
  def __init__(self, lado):
    self.lado = lado
  def set_lado(self, lado):
    self.lado = lado
  def get_lado(self):
    return self.lado
class Rectangulo(Cuadrado):
  def __init__(self, lado, ancho):
    super().__init__(lado)
    self.ancho = ancho
// Principio de sustitución de Liskov:
// Las clases derivadas deben ser sustituidas por sus clases base
class Cuadrado {
  private int lado;
  public void SetLado(int lado) {
    this.lado = lado;
  }
  public int GetLado() {
    return lado;
  }
}
class Rectangulo : Cuadrado {
  private int ancho;
  public void SetAncho(int ancho) {
    this.ancho = ancho;
  }
}
// Principio de sustitución de Liskov:
// Las clases derivadas deben ser sustituibles por sus clases base
class Cuadrado {
  private lado: number;
  setLado(lado: number): void {
    this.lado = lado;
  }
  getLado(): number {
    return this.lado;
  }
}
class Rectangulo extends Cuadrado {
  private ancho: number;
  setAncho(ancho: number): void {
    this.ancho = ancho;
  }
}
10 ¿Qué es el principio de segregación de interfaces? // Principio de segregación de interfaces:
// Una interfaz debe ser específica y no obligar a las clases a implementar métodos que no usan
interface IAnimal {
  void comer();
}
interface IVuelo {
  void volar();
}
class Pajaro implements IAnimal, IVuelo {
  public void comer() {
    System.out.println("El pájaro come");
  }
  public void volar() {
    System.out.println("El pájaro vuela");
  }
}
# Principio de segregación de interfaces:
# Una interfaz debe ser específica y no obligar a las clases a implementar métodos que no usan
class IAnimal:
  def comer(self):
    pass
class IVuelo:
  def volar(self):
    pass
class Pajaro(IAnimal, IVuelo):
  def comer(self):
    print("El pájaro come")
  def volar(self):
    print("El pájaro vuela")
// Principio de segregación de interfaces:
// Una interfaz debe ser específica y no obligar a las clases a implementar métodos que no usan
interface IAnimal {
  void Comer();
}
interface IVuelo {
  void Volar();
}
class Pajaro : IAnimal, IVuelo {
  public void Comer() {
    Console.WriteLine("El pájaro come");
  }
  public void Volar() {
    Console.WriteLine("El pájaro vuela");
  }
}
// Principio de segregación de interfaces:
// Una interfaz debe ser específica y no obligar a las clases a implementar métodos que no usan
interface Animal {
  comer(): void;
}
interface Vuelo {
  volar(): void;
}
class Pajaro implements Animal, Vuelo {
  comer(): void {
    console.log("El pájaro come");
  }
  volar(): void {
    console.log("El pájaro vuela");
  }
}