Clases Derivadas


La programación orientada a objetos extiende los tipos abstractos de datos permitiendo relaciones tipo-subtipo. Esto es alcanzado a través de un mecanismo denominado herencia. Más que reimplementar características compartidas, una clase puede heredar datos y funciones miembros de otras clases. En C++, este mecanismo es implementado a través de la derivación de clases.

Especificación de derivación

Veamos el siguiente ejemplo:

// clases que sirven como clases base
class Animal{...};
class EnExtincion{...};
class Carnivoro{...};
class Herbivoro{...};

// Derivación simple
class Oso:public Animal { ...};

// Derivaciones múltiples
class Gato : public Animal, Carnivoro {...};
class Panda : private EnExtincion, public Oso, private Herbivoro {...};

Si se omite un atributo de público,privado o protegido a la clase base, esta es manipulada como privada. En el caso de la clase gato, Carnivoro es una clase base privada.

Una clase derivada puede servir como clase base para subsecuentes derivaciones.

La sintaxis para definir clases bases es igual a definir clases ordinarias, con las siguientes dos excepciones:

El acceso desde clases derivadas a miembros heredados es como si fueran miembros propios (depende del tipo de herencia realizada). Tambien puede usarse el class scope operator es decir, para acceder al miembro A de la clase ClassA desde el objeto Obj de la clase ClassB sería Obj.ClassA::A o bien Obj.A.

Existen dos casos que requieren el uso de la notación extendida:

class ObjetoGrafico
{
  protected:
    int Visible;
    int X,Y;
  public:
    ObjetoGrafico(int A, int B): X(A), Y(B), Visible(0){};
    virtual void Draw() = 0;
    virtual void Hide() = 0;
    virtual ~ObjetoGrafico(){}
};
class Circulo: public ObjetoGrafico
{
  private:
    int Radio;
  public:
    Circulo(int A, int B, int R):ObjetoGrafico(A,B), Radio(R){};
    void Draw(){...};
    void Hide(){...};
    ~ObjetoGrafico(){Hide();}
};
class CirduloLleno: public Circulo
{
  private:
    int Patron;
  public:
    CirculoLleno(int A, int B, int R, int P):Circulo(A,B,R), Patron(P){...}
    void Draw(){Circulo::Draw();...};
    void Hide(){...};
};

Ocultamiento de la información bajo derivación

Un miembro protegido de una clase es público para las funciones miembro, amigo para las clases derivadas y privado para el resto del programa. Una clase derivada no posee acceso privilegiado a miembros privados de una clase base.

Clases bases públicas y derivadas

Los miembros heredados de una clase base pública mantienen su nivel de acceso dentro de la clase derivada. En general, en una jerarquía de derivación pública, cada clase derivada subsecuentemente tiene acceso combinado a miembros públicos y protegidos de las clases bases previas en una rama.

Los miembros públicos y protegidos heredados a través de una derivación protegida, se vuelen miembros protegidos de la clase derivada.

Los miembros públicos y protegidos heredados a traves de una derivación privada se vuelven miembros privados de la clase derivada. Esto lleva a:

Conversiones estándar bajo derivación

Existen 4 conversiones predefinidas que son aplicables entre una clase derivada y su clase base pública:

Adicionalmente, un puntero a cualquier objeto será implícitamente convertido en un puntero del tipo void * (Para asignar este a un puntero a otro tipo hace falta el uso de cast explícito.).