C++ Herencia


Ejemplo

Las clases / estructuras pueden tener relaciones de herencia.

Si una clase / estructura B hereda de una clase / estructura A , esto significa que B tiene como padre A Decimos que B es una clase / estructura derivada de A , y A es la clase / estructura base.

struct A
{
public:
    int p1;
protected:
    int p2;
private:
    int p3;
};

//Make B inherit publicly (default) from A
struct B : A
{
};

Hay 3 formas de herencia para una clase / estructura:

  • public
  • private
  • protected

Tenga en cuenta que la herencia predeterminada es la misma que la visibilidad predeterminada de los miembros: public si usa la palabra clave struct , y private para la palabra clave class .

Incluso es posible tener una class derivada de una struct (o viceversa). En este caso, la herencia predeterminada está controlada por el hijo, por lo que una struct que se deriva de una class se establecerá de forma predeterminada como herencia pública, y una class que se deriva de una struct tendrá herencia privada de forma predeterminada.

herencia public :

struct B : public A // or just `struct B : A`
{
    void foo()
    {
        p1 = 0; //well formed, p1 is public in B
        p2 = 0; //well formed, p2 is protected in B
        p3 = 0; //ill formed, p3 is private in A
    }
};

B b;
b.p1 = 1; //well formed, p1 is public
b.p2 = 1; //ill formed, p2 is protected
b.p3 = 1; //ill formed, p3 is inaccessible

herencia private

struct B : private A
{
    void foo()
    {
        p1 = 0; //well formed, p1 is private in B
        p2 = 0; //well formed, p2 is private in B
        p3 = 0; //ill formed, p3 is private in A
    }
};

B b;
b.p1 = 1; //ill formed, p1 is private
b.p2 = 1; //ill formed, p2 is private
b.p3 = 1; //ill formed, p3 is inaccessible

herencia protected :

struct B : protected A
{
    void foo()
    {
        p1 = 0; //well formed, p1 is protected in B
        p2 = 0; //well formed, p2 is protected in B
        p3 = 0; //ill formed, p3 is private in A
    }
};

B b;
b.p1 = 1; //ill formed, p1 is protected
b.p2 = 1; //ill formed, p2 is protected
b.p3 = 1; //ill formed, p3 is inaccessible

Tenga en cuenta que aunque se permite la herencia protected , el uso real de la misma es raro. Una instancia de cómo se usa la herencia protected en la aplicación es en la especialización de clase base parcial (generalmente denominada "polimorfismo controlado").

Cuando la POO era relativamente nueva, se decía con frecuencia que la herencia (pública) modelaba una relación "IS-A". Es decir, la herencia pública es correcta solo si una instancia de la clase derivada es también una instancia de la clase base.

Más tarde, esto se refinó en el Principio de Sustitución de Liskov : la herencia pública solo debe usarse cuando / si una instancia de la clase derivada puede sustituirse por una instancia de la clase base bajo cualquier circunstancia posible (y aún tiene sentido).

En general, se dice que la herencia privada incorpora una relación completamente diferente: "se implementa en términos de" (a veces se denomina relación "HAS-A"). Por ejemplo, una clase de Stack podría heredar de forma privada de una clase Vector . La herencia privada tiene una similitud mucho mayor con la agregación que con la herencia pública.

La herencia protegida casi nunca se usa, y no hay un acuerdo general sobre qué tipo de relación abarca.