No tienes acceso a esta clase

¡Continúa aprendiendo! Únete y comienza a potenciar tu carrera

Herencia múltiple

14/16
Recursos

¿Qué es la herencia múltiple en la programación orientada a objetos?

La herencia es uno de los pilares fundamentales de la programación orientada a objetos, permitiendo que las clases hereden características y comportamientos de otras. Pero, ¿qué pasa cuando una clase necesita heredar de más de una clase base? Aquí es donde entra en juego la herencia múltiple, un concepto poderoso que C++ implementa para ofrecer una mayor flexibilidad en la construcción de programas.

¿Cómo se implementa la herencia múltiple en C++?

La herencia múltiple en C++ permite que una clase derive de más de una clase base. Para ilustrar cómo se implementa, consideremos un ejemplo donde tenemos una clase base Animal y dos clases derivadas Herbívor y Carnívor. Si queremos crear un Omnívoro, que herede las propiedades de ambos, herbívoro y carnívoro, podemos hacerlo mediante la herencia múltiple de la siguiente manera:

class Omni : public Herb, public Carn {
   public:
      Omni() : Herb(), Carn() {
          // Implementación del constructor
      }
};

¿Cómo manejar conflictos y ambigüedades?

Cuando una clase hereda de múltiples clases base, puede surgir la ambigüedad, especialmente si las clases base tienen métodos o propiedades con el mismo nombre. C++ aborda esta situación permitiendo especificar de qué clase base se debe llamar un método. Por ejemplo:

Omni o;
o.Herb::comer();  // Llama a la versión del método `comer` de la clase Herb
o.Carn::comer();  // Llama a la versión del método `comer` de la clase Carn

¿Cómo redefinir métodos en una clase derivada?

Para eliminar completamente la ambigüedad y personalizar el comportamiento de una clase que utiliza herencia múltiple, se puede redefinir un método en la clase derivada. Imaginemos que queremos que Omni tenga su propia versión del método comer:

class Omni : public Herb, public Carn {
   public:
      Omni() : Herb(), Carn() {}

      void comer() {
          std::cout << "Este animal come lo que sea." << std::endl;
      }
};

De esta forma, al invocar el método comer de un objeto de tipo Omni, se ejecutará la versión personalizada, eliminando toda ambigüedad.

¿Qué más puedo aprender sobre herencia y programación orientada a objetos?

La herencia múltiple es solo uno de los muchos conceptos avanzados en programación orientada a objetos. Si te interesa profundizar más, considera explorar cursos y materiales educativos adicionales sobre estos temas. La plataforma Platzi, por ejemplo, ofrece cursos detallados sobre programación orientada a objetos, que abordan desde los fundamentos hasta técnicas más avanzadas del diseño de software.

Un enfoque robusto del aprendizaje y la práctica continua te llevará a entender profundamente no solo la herencia múltiple, sino también otros conceptos como el polimorfismo, las interfaces y el encapsulamiento. ¡Sigue explorando, y pronto dominarás los secretos de la programación orientada a objetos!

Aportes 8

Preguntas 4

Ordenar por:

¿Quieres ver más aportes, preguntas y respuestas de la comunidad?

Codigo:

#include <iostream>
#include <string>

using namespace std;

class Animal {
protected:
    static int numero_animales;
    string alimento;
public:
    Animal();
    ~Animal();
    static int obtenerNumeroAnimales();
    string obtenerAlimento(){
        return alimento;
    };
    void comer(){
        cout<<"Este animal está comiendo " <<alimento<<"... ñom ñom"<<endl;
    };
};

int Animal::numero_animales = 0;

Animal::Animal()
{
    cout<<"Creando nuevo animal ... "<<endl;
    numero_animales += 1;
}

Animal::~Animal()
{
    cout<<"Borrando animal..."<<endl;
    numero_animales-=1;
}

int Animal::obtenerNumeroAnimales()
{
    return numero_animales;
}

class Herviboro : public Animal {
public:
    Herviboro():Animal(){
        this->alimento = "plantas ";
    }
    void pastar(){
        cout<<"Este animal está pasteando ..."<<endl;
    }
};

class Carnivoro : public Animal {
public:
    Carnivoro():Animal(){
        this->alimento = "plantas ";
    }
    void cazar(){
        cout<<"Este animal está cazando ..."<<endl;
    }
};

class Omnivoro : public Herviboro, public Carnivoro{
public: 
    Omnivoro():Herviboro(),Carnivoro(){}
    void comer(){
        cout<<"Este animal come lo que sea ...."<<endl;
    }
};

int main(){
    Animal *a = new Animal();
    Herviboro *h = new Herviboro();
    Carnivoro *c = new Carnivoro();
    Omnivoro *o = new Omnivoro();

    cout<<"Numero de animeles: "<<Animal::obtenerNumeroAnimales()<<endl;
    
    a->comer();
    
    h->pastar();
    h->comer();

    c->cazar();
    c->comer();
    cout<<"omnivoro"<<endl;
    o->comer();

    delete a;
    cout<<"Numero de animales"<<Animal::obtenerNumeroAnimales()<<endl;
}

Hola, quería comentar que en la clase Omnivoro algo no quedo bien. Si nos fijamos cuenta 5 animales, cuando deberían ser 4.
Entiendo que algo del constructor no quedo bien, ya que esta pasando 2 veces por el constructor Animal.
No se si estoy en lo correcto.

class Omnivoro : public Herviboro, public Carnivoro {
    public:
        Omnivoro() : Herviboro(), Carnivoro() {}
        void comer() {
            cout << "Este animal como lo que sea..." << endl;
        }
};

int main() {
    Animal *a = new Animal();
    Herviboro *h = new Herviboro();
    Carnivoro *c = new Carnivoro();
    Omnivoro *o = new Omnivoro();

    cout << "Numero de animales " << Animal::obtenerNumeroAnimales() << endl;
    
    a->comer();
    
    h->pastar();
    
    h->comer();
    
    c->cazar();
    
    c->comer();

    cout << "Omnivoro" << endl;
    o->comer();
    
    delete a;
    cout << "Numero de animales " << Animal::obtenerNumeroAnimales() << endl;    
}
#include <iostream>
#include <conio.h>
#include <stdlib.h>
#include <string>
#include <locale.h>

using namespace std;
class Mounstro {
protected:
	static int numeroMounstros;
	string alimento;
public:
	Mounstro();
	~Mounstro();
	static int obtenerNumeroMounstros();
	string obtenerAlimento() {
		return alimento;
	}
	void comer() {
		cout << "Este mounstro está comiendo " << alimento << " rico, rico " << endl;
	}
	
};

int Mounstro::numeroMounstros = 0;
Mounstro::Mounstro()
{
	cout << "Creando nuevo mounstro...." << endl;
	numeroMounstros += 1;
}
int Mounstro::obtenerNumeroMounstros()
{
	return numeroMounstros;
}
Mounstro::~Mounstro()
{
	cout << "borrando bicho...." << endl;
	numeroMounstros -= 1;
}
class Herviboro : public Mounstro{
public:
	Herviboro() : Mounstro() {
		this->alimento = "plantas";
}
	void pastar() {
		cout << "Este animal está pastando... " << endl;
	}
};

class Carnivoro : public Mounstro {
public :
	Carnivoro() : Mounstro() {
		this->alimento = "carne";
	}
	void cazar() {
		cout << "Este animal está cazando..." << endl;
	}
};

class Omnivoro : public Herviboro, public Carnivoro {
public:
	Omnivoro() : Herviboro(), Carnivoro(){}
	void comer() {
		cout << "este animal come cualquier cosa " << endl;
	}
};


	int main() {
		setlocale(LC_ALL, "");

		Mounstro* m = new Mounstro();
		Herviboro* h = new Herviboro();
		Carnivoro* c = new Carnivoro();
		Omnivoro* o = new Omnivoro();
		cout << "Numero de mounstros: " << Mounstro::obtenerNumeroMounstros() << endl;
		m->comer();
		h->pastar();
		h->comer();
		c->cazar();
		c->comer();
		cout << "omnivoro" << endl;
		o->comer();
		delete m;
		cout << "Numero de mounstros: " << Mounstro::obtenerNumeroMounstros() << endl;
	getch();
};

Algo que aclarar que cuando se crea un Omnívoro, como llama a función de crear tanto de Herbívoro como de Carnívoro, el contador de animales suma 2 en vez de uno.

Crear una clase en C++ que extiende de 2 clases utilizando la herencia múltiple.

Mi codigo:

#include <iostream>
#include <string>
using namespace std;
//Crear objeto
class Animal{
  //private:
  protected:
  static int numero_animales;
  string alimento;
  public:
  Animal();
  ~Animal();
  static int obtenerNumeroAnimales();
  string obtenerAlimento(){
    return alimento;
  }
  void comer(){
    cout<<"Este animal esta comiendo "<<alimento<<". . . yomi yomi"<<endl;
  }
};
//Inicializar variable
int Animal::numero_animales = 0;
//Constructor y Destructor
Animal::Animal(){
  cout<<"Creando nuevo animal..."<<endl;
  numero_animales +=1;
}
Animal::~Animal(){
  cout<<"Borrando animal ..."<<endl;
  numero_animales -=1;
}
int Animal::obtenerNumeroAnimales(){
  return numero_animales;
}

//Clase que Hereda
class Herviboro : public Animal{
  public:
    Herviboro() : Animal(){
      this->alimento = "plantas";
    }
    void pastar(){
      cout<<"Este animal esta pastando ..."<<endl;
    }
};

class Carnivoro : public Animal{
  public:
  Carnivoro() : Animal(){
    this->alimento= "carne";
  }
  void cazar(){
    cout<<"Este animal esta cazando ..."<<endl;
  }
};

class Omnivoro : public Herviboro, public Carnivoro{
  public:
  Omnivoro() : Herviboro(),Carnivoro(){}
  void comer(){
    cout<<"Este animal come lo que sea..."<<endl;
  }
};

int main(){
  Animal *a1 = new Animal();
  Herviboro *h1 = new Herviboro();
  Carnivoro *c1 = new Carnivoro();
  Omnivoro *o1 = new Omnivoro();
  cout<<"Numero de animales: "<<Animal::obtenerNumeroAnimales()<<endl;
  a1->comer();
  h1->pastar();
  //Plantas
  h1->comer();
  c1->cazar();
  //Carne
  c1->comer();
  //? Ominvoro
  //o1->Herviboro::comer(); //Plantas() de sus Padres
  //o1->Carnivoro::comer(); //Carne() de sus Padres
  o1->comer(); //En su propio constructor
  delete a1,h1,c1,o1;
  cout<<"Numero de animales: "<<Animal::obtenerNumeroAnimales()<<endl;
}

A la hora de heredar si se pone un virtual, se soluciona el problema del diamante

class Omnivoro : virtual public Herviboro, virtual public Carnivoro