Escolar Documentos
Profissional Documentos
Cultura Documentos
Herencia
2.1. INTRODUCCIN
La herencia es la caracterstica fundamental que distingue un lenguaje orientado
a objetos, como el C++, de otro convencional como C, BASIC, etc. C++ permite
heredar las clases caractersticas y conductas de una o varias clases denominadas base.
Las clases que heredan de clases base se denominan derivadas. Estas a su vez pueden
ser clases bases para otras clases derivadas. Se establece as una clasificacin jerrquica,
similar a la clasificacin existente en Biologa con los animales y las plantas.
La herencia es el concepto que permite a los programadores utilizar de nuevo y
extender el cdigo existente. La herencia mejora la confianza en los programas y
disminuye el tiempo de desarrollo de los mismos. Los programadores crean clases base:
Cuando se dan cuenta de que diversos tipos tienen algo en comn, por ejemplo,
en el juego del ajedrez, peones, alfiles, rey, reina, caballos y torres son piezas del
juego. Creamos, por tanto, una clase base y derivamos cada pieza individual a
partir de dicha clase base.
20
Punto
Punto Mejorado
21
22
23
//...
}
El objeto pm de la clase PuntoMejorado, al salir de la funcin principal, llama a
su destructor y al de sus clases base. Por tanto, el orden de llamada a los destructores es
inverso al orden de llamada a los constructores. Si ahora escribimos:
PuntoMejorado* ptro_pm= new PuntoMejorado(10,15);
delete ptro_pm;
24
}
Se incremento tambin la funcionalidad de la clase derivada, definiendo una
funcin denominada mover, que desplaza el punto desde una posicin (x, y) a una nueva
posicin (x+dx, y+dy). Primero borra el punto de la posicin previa llamando a la
funcin miembro ocultar, y lo pone en la nueva posicin, llamando a la funcin
mostrar.
void PuntoMejorado::mover(int dx, int dy)
{
ocultar();
x+=dx;
y+=dy;
mostrar();
}
25
pm.getx();
2.3. POLIMORFISMO
Polimorfismo es una palabra griega que significa muchas formas. En el lenguaje
habitual usamos una misma palabra cuyo significado difiere segn sea el contexto. El
polimorfismo describe una de las facetas ms interesantes y oscuras para los
principiantes del lenguaje C++: el distinto comportamiento del programa dependiendo
de la situacin en tiempo de ejecucin de dicho programa.
El polimorfismo se implementa por medio de las denominadas funciones
virtuales. Dichas funciones permiten a las clases derivadas proporcionar diferentes
versiones de la funcin definida en la clase base. En la clase derivada se declara y
define una funcin que tiene el mismo nombre, el mismo nmero de argumentos y del
mismo tipo que en la clase base, pero que da lugar a un comportamiento distinto,
especfico del objeto perteneciente a dicha clase derivada.
26
La clase Figura
La clase abstracta Figura, tiene corno miembros la posicin x e y de la figura
Figura
Elipse
Rectngulo
Crculo
Cuadrado
class Figura{
protected:
int x;
int y;
public:
Figura(int _x, int _y);
virtual ~Figura(){cout<<Destructor de Figura\n;}
virtual float area(void)=0;
};
El constructor inicializa los miembros dato:
Figura::Figura(int _x, int _y)
{
x=_x; y=_y;
}
El destructor imprime un mensaje:
class Figura{
//...
virtual ~Figura() {cout<<Destructor de Figura\n;}
};
28
La clase Rectngulo
Las clases derivadas heredan los miembros dato x e y de la clase base, y
redefinen la funcin rea, declarada virtual en la clase base Figura, ya que cada figura
particular tiene una frmula distinta para calcular su rea. Por ejemplo, la clase derivada
Rectngulo tiene como datos, aparte de su posicin (x, y) en el plano, sus dimensiones,
es decir, su anchura Lx y altura Ly.
class Rectangulo:public Figura{
protected:
int Lx, Ly;
public:
Rectangulo(int _x, int _y, int _Lx, int _Ly);
~Rectangulo(){cout<<Destructor de Rectngulo\n;}
float area(void);
};
El constructor de la clase Rectngulo llama al constructor de la clase Figura, le
pasa las coordenadas de su centro, y luego inicializa los miembros dato Lx y Ly.
Rectangulo::Rectangulo (int _x, int _y, int _Lx, int _Ly)
:Figura(_x, _y)
{
Lx = _Lx; Ly = _Ly;
}
En la redefinicin de la funcin rea, se calcula el rea del rectngulo como
producto de la anchura por la altura.
float Rectangulo::area(void)
{
return Lx*Ly;
}
29
La clase Cuadrado
La clase Cuadrado es una clase especializada de Rectngulo, ya que un
La clase Elipse
La clase derivada Elipse tiene como datos, aparte de su posicin (x, y) en el
plano, sus dimensiones, es decir, su semieje mayor rMayor y semieje menor rMenor.
class Elipse:public Figura{
protected:
float rMayor, rMenor;
public:
Elipse(int _x, int _y, float rl, float r2);
~Elipse(){cout<<Destructor de Elipse\n;}
float area(void);
};
El constructor de la clase Elipse llama al constructor de la clase Figura, le pasa
las coordenadas de su centro, y luego inicializa los miembros dato rMayor y rMenor.
30
La clase Circulo
La clase Circulo es una clase especializada de Elipse, ya que una circunferencia
31
32
enlace tardo para una funcin declarndola virtual. Para comprobar, se crea un array
de punteros a objetos de la clase base Figura, y se guardan en sus elementos las
direcciones de objetos de las clases derivadas.
const int N=4;
Figura** figura=new Figura* [N];
figura[0]=new Elipse(120, 80, 5.0, 7.0);
figura[l]=new Circulo(300, 80, 5.0);
figura[2]=new Rectangulo(150, 300, 5.0, 7. 0);
figura[3]=new Cuadrado(300, 300, 7.0);
La sentencia:
ptro_Fig[i]area();
a qu funcin arca llamar? La respuesta ser segn sea el ndice i. Si i es cero,
el primer elemento del array contiene la direccin de un objeto de la clase Elipse, y
luego llamar a area de Elipse. Si i es uno, el segundo elemento del array guarda la
direccin de un objeto de la clase Circulo, luego llamar a area de Circulo, y as
sucesivamente. Pero si el valor del ndice i se introduce en tiempo de ejecucin (run
time):
cin>>i;
luego la decisin sobre qu funcin area se va a llamar se retrasa hasta el tiempo de
ejecucin, tal como se muestra en la siguiente porcin de cdigo.
int i;
while(1){
cout<<Escoge la figura: \n;
cout<< 0.Una elipse.-\n;
cout<<..1.Un crculo.-\n;
cout<< 2.Un rectngulo.-\n;
cout<< 3.Un cuadrado.-\n;
cout<< 4.Salir ;
cout<<\n
: >;
cin>>i;
if (i >= 4) break;
33
cout<<rea= <<ptro_Fig[i]area()<<\n;
clrscr();
};
34
35
36
Figura* ptr_Fig;
ptr_Fig=new Rectangulo (150,. 300, 5. 0, 7. 0);
Cuando se escribe:
delete ptr_Fig;
se llamar al destructor de Rectangulo seguido del destructor de Figura. Si el destructor
no estuviese declarado virtual, se llamara solamente al destructor de Figura,
destruyendo incorrectamente el objeto al que apunta ptr_Fig. Cuando se destruye el
array fgura, podemos observar la secuencia de las llamadas a los destructores, primero
de las clases deriva- das y luego de las clases base Figura.
for(i=0; i<N; i++)
delete figura [i];
La clase TValidator
TValidator es una clase base abstracta, del mismo modo que lo es Figura en la
jerarqua de clases que describen las figuras planas. No se pueden crear objetos de una
clase abstracta, pero proporciona un interfaz comn para las clases derivadas de ella.
class TValidator{
public:
Tvalidator(){};
virtual ~Tvalidator(){};
virtual void Error()=0;
virtual BOOL IsValid(const char* str)=0;
37
TStringLookupValidator
TFilterValidator
TRangeValidator
La clase TFilterValidator
La clase TFilterValidator tiene como misin filtrar los caracteres que estn
permitidos. As, si se espera que la entrada sea el nmero del DNI, no se podrn
introducir caracteres alfabticos. Si en el control de edicin se ha de introducir el
nombre y apellidos de una persona, no pueden aparecer caracteres numricos, etc.
38
return FALSE;
return TRUE;
}
La funcin miembro Error se redefine para emitir un mensaje de error
significativo.
39
void TFilterValidator::Error()
{
cout<<Ha introducido caracteres que no estn permitidos\n;
}
g
La clase TRangeValidator
La clase TRangeValidator derivar de TFilterValidator, ya que primero ha de
verificar que los caracteres introducidos son numricos y, en segundo lugar, que el
nmero est en un intervalo predeterminado. Los miembros datos de esta clase son el
valor entero mayor Max, y el menor Min que puede introducirse en el control de
edicin.
class TrangeValidator: public TFilterValidator {
protected:
int Max;
int Min;
public:
TRangeValidator (int min, int max)
void Error();
BOOL IsValid(const char* str);
};
El constructor crea un objeto de la clase TRangeValidator, llamando primero al
constructor de la clase TFilterValidator pasndole el conjunto de caracteres permitidos,
los dgitos del 0 al 9, el signo + y -. Luego, inicializa Min con el valor de min y Max con
el valor de max, establecindose as el intervalo de valores permitidos.
TRangeValidator::TRangeValidator(int min, int max)
:TFilterValidator(01234567890+-)
{
Max=max;
Min=min;
}
40
nmero
introducido
no
est
en
el
intervalo
(<<Min<<,<<Max<<)\n;
}
g
La clase TStringLookupValidator
Esta clase verifica el dato introducido en el control de edicin asociado
buscando en una coleccin de cadenas de caracteres que son vlidas. Por ejemplo, para
un envo postal, se ha de introducir en el control de edicin correspondiente el nombre
de la provincia, o el cdigo postal. Podemos asociar a dicho control un objeto de la
clase TStringLookupValidator que tenga como coleccin de cadenas de caracteres
vlidas el nombre de todas las provincias.
Los miembros dato son el nmero de elementos de la coleccin, Items, y un
array de punteros a caracteres, Strings.
class TStringLookupValidator: public TValidator{
protected:
char** Strings;
int Items;
41
public:
TStringLookupValidator(char** strings, int items);
~TstringLookupValidator();
void Error();
BOOL IsValid(const char* str);
}
El constructor reserva espacio para el array Strings e inicializa los miembros
dato con la informacin que se le pasa en los argumentos al constructor.
TStringLookupValidator. :TStringLookupValidator(char** strings, int items)
:Tvalidator()
{
Items=items;
Strings= new char*[Items];
for(int i=0; i<Items; i++){
Strings[i]=new char[strlen(strings[i])+1];
strcpy(Strings[i], strings[i]);
}
}
El destructor libera el espacio reservado para el array de punteros a char cuando
ya no es necesario.
TStringLookupValidator::~TstrngLookupValidator()
{
for(int i=0; i<Items; i++)
delete[] Strings[i];
delete Strings;
}
La funcin IsValid busca si la cadena de caracteres str est en el array Strings.
Para ello emplea la funcin strcmp de la librera STRING.H.
42
43
public:
TEdit(int maxChars);
~Tedit();
void SetValidator(TValidator* validator);
void GetLine(const char* contenido);
BOOL CanClose();
};
En el constructor, reservamos espacio para el array de caracteres intro, e
inicializamos los otros miembros dato.
TEdit::TEdit(int maxChars)
{
intro= new char[maxChars+1];
dim=maxChars;
Validator=0;
}
En el destructor liberamos el espacio reservado para el array, y destruimos el
verificador asociado al control de edicin.
TEdit::~Tedit()
{
delete[] intro;
delete Validator;
}
La funcin SetValidator inicializa el miembro dato Validator con posterioridad a
la creacin del objeto control de edicin.
void TEdit::SetValidator(TValidator* validator)
{
Validator=validator;
}
La funcin GetLine lee los caracteres introducidos en el control de edicin, hasta
un mximo de dim caracteres. El mximo nmero de caracteres que se pueden
44
Supongamos en primer lugar que el control de edicin est pensado para introducir
el nombre y apellidos de una persona; por tanto, asociaremos al control de edicin
un objeto verificador que filtre solamente caracteres alfabticos y rechace los
numricos.
45
47
Rectangulo
RectRedondo
class Rectangulo{
protected:
float altura;
float anchura;
public:
Rectangulo (float h, float w) {altura=h;. anchura=w;}
float mostrar(){return altura;}
};
48
cout<<Rr.area()<<\n;
cout<<Rr.mostrar()<<\n;
cout<<Rr.getcolor()<<\n;
Punto
Circulo
Rectangulo
RectRedondo
51