BUSCAR
INDICE
INDICE DEL TEMA
OBJETIVOS
TEORIA
PALABRAS RESERVADAS
GLOSARIO
EJERCICIOS
RESUELTOS
AUTOEVALUACION
PROPUESTOS
ERRORES
ESTADISTICAS
INICIO
FAQS
LINKS
RECOMIENDANOS
QUIENES SOMOS
MAPA DEL WEB
COLABORAR
Tema 19 Herencia
Teoría: Variables y funciones miembro protected

Uno de los problemas que aparece con la herencia es el del control del acceso a los datos. ¿Puede una función de una clase derivada acceder a los datos privados de su clase base? En principio una clase no puede acceder a los datos privados de otra, pero podría ser muy conveniente que una clase derivada accediera a todos los datos de su clase base. Para hacer posible esto, existe el tipo de dato protected. Este tipo de datos es privado para todas aquellas clases que no son derivadas, pero público para una clase derivada de la clase en la que se ha definido la variable como protected.

Por otra parte, el proceso de herencia puede efectuarse de dos formas distintas: siendo la clase base public o private para la clase derivada. En el caso de que la clase base sea public para la clase derivada, ésta hereda los miembros public y protected de la clase base como miembros public y protected, respectivamente. Por el contrario, si la clase base es private para la clase derivada, ésta hereda todos los datos de la clase base como private.

Como ejemplo, se puede pensar en dos tipos de cuentas bancarias que comparten algunas características y que también tienen algunas diferencias. Ambas cuentas tienen un saldo, un interés y el nombre del titular de la cuenta. La cuenta joven es un tipo de cuenta que requiere la edad del propietario, mientras que la cuenta empresarial necesita el nombre de la empresa. El problema podría resolverse estableciendo una clase base llamada C_Cuenta y creando dos tipos de cuenta derivados de dicha clase base.

Para indicar que una clase deriva de otra es necesario indicarlo en la definición de la clase derivada, especificando el modo -public o private- en que deriva de su clase base:

class Clase_Derivada : public o private Clase_Base

De esta forma el código necesario para crear esas tres clases mencionadas quedaría de la siguiente forma:

#include <iostream.h>

class C_Cuenta {
// Variables miembro

private:

char *Nombre; // Nombre de la persona
double Saldo; // Saldo Actual de la cuenta
double Interes; // Interés aplicado

public:

// Constructor
C_Cuenta(const char *unNombre, double unSaldo=0.0, double unInteres=0.0)
{

Nombre = new char[strlen(unNombre)+1];
strcpy(Nombre, unNombre);
SetSaldo(unSaldo);
SetInteres(unInteres);

}

// Destructor
~Cuenta()
{ delete [] Nombre; }
// Métodos
inline char *GetNombre()
{ return Nombre; }
inline double GetSaldo()
{ return Saldo; }

inline double GetInteres()
{ return Interes; }
inline void SetSaldo(double unSaldo)
{ Saldo = unSaldo; }
inline void SetInteres(double unInteres)
{ Interes = unInteres; }
inline void Ingreso(double unaCantidad)
{ SetSaldo( GetSaldo() + unaCantidad ); }

friend ostream& operator<<(ostream& os, C_Cuenta& unaCuenta)
{

os << "Nombre=" << unaCuenta.GetNombre() << endl;
os << "Saldo=" << unaCuenta.GetSaldo() << endl;
return os;

}

};

class C_CuentaJoven : public C_Cuenta {

private:

int Edad;

public:

// argumentos del constructor

C_CuentaJoven( const char *unNombre, int laEdad, double unSaldo=0.0, double unInteres=0.0)
: C_Cuenta(unNombre, unSaldo, unInteres)
// se llama al constructor de la clase base en la línea previa.
{

Edad = laEdad;

}

};

class C_CuentaEmpresarial : public C_Cuenta {

private:

char *NomEmpresa;

public:

C_CuentaEmpresarial( // argumentos del constructor
const char *unNombre,
const char *laEmpresa,
double unSaldo=0.0,
double unInteres=0.0)
: C_Cuenta(unNombre, unSaldo, unInteres)
// se llama al constructor de la clase base en la línea previa.
{

NomEmpresa = new char[strlen(laEmpresa)+1];
strcpy(NomEmpresa, laEmpresa);

}
// Cuando una variable de este tipo se destruye se llamará
// primero el destructor de CuentaEmpresarial y posteriormente se
// llama automáticamente el destructor de la clase base.
~C_CuentaEmpresarial()
{ delete [] NomEmpresa; }

};

Si un miembro heredado se redefine en la clase derivada, el nombre redefinido oculta el nombre heredado que ya queda invisible para los objetos de la clase derivada.

Hay algunos elementos de la clase base que no pueden ser heredados:
· Constructores
· Destructores
· Funciones friend
· Funciones y datos estáticos de la clase
· Operador de asignación (=) sobrecargado