PDF de programación - Tema 3: Herencia en C++

Imágen de pdf Tema 3: Herencia en C++

Tema 3: Herencia en C++gráfica de visualizaciones

Publicado el 24 de Enero del 2017
1.234 visualizaciones desde el 24 de Enero del 2017
108,7 KB
44 paginas
Creado hace 15a (24/11/2008)
Tema 3: Herencia en C++

Programación Orientada a Objetos

Curso 2008/2009
Begoña Moros Valle

Contenido

Tipos de herencia
Herencia y niveles de visibilidad
Herencia y creación
Redefinición de métodos
Conversión de tipos
Consulta del tipo dinámico
Clases abstractas
Punteros a función
Iteradores
Herencia múltiple

Tema 3

Herencia

2

Caso de estudio

Deposito
titular
capital
plazoDias
tipoInteres

liquidar

getIntereses

DepositoEstructurado
tipoInteresVariable

capitalVariable

Un depósito estructurado es_un

tipo de depósito

Un depósito estructurado tiene

nuevos atributos
Tipo de interés variable
Capital variable

Redefine parte de la

funcionalidad heredada de
depósito
El método que calcula los intereses
El método que devuelve el capital

Tema 3

Herencia

3

Clase Deposito

class Deposito {
private:

public:

Persona* titular;
double capital;
int plazoDias;
double tipoInteres;
Deposito(…);
double liquidar();
double getIntereses();
double getCapital();
int getPlazoDias();
double getTipoInteres();
Persona* getTitular();

};

Tema 3

Herencia

4

Clase Depósito Estructurado

class DepositoEstructurado: public Deposito{
private:

double tipoInteresVariable;
double capitalVariable;

public:
DepositoEstructurado(Persona titular, double capital, int
plazoDias,double tipoInteres, double tipoInteresVariable,
double capitalVariable);

double getInteresesVariable();
void setTipoInteresVariable(double interesVariable);
double getTipoInteresVariable();
double getCapitalVariable();

};

Tema 3

Herencia

5

Niveles de visibilidad

private

protected

public

Sólo accesible en la clase

donde se definen las
propiedades

Sólo accesibles por la

clase y sus
descendientes

Accesible desde cualquier

clase

Tema 3

Herencia

6

Herencia pública

class B: public A {...}

Por defecto, se mantiene el nivel de visibilidad

de las propiedades heredadas (= Java)

Se puede ampliar la visibilidad de las

características heredadas

Se puede reducir la visibilidad de las

características heredadas
“agujero de tipos” debido a asignaciones

polimórficas

Tema 3

Herencia

7

Herencia privada

class B: private A {...}

Todas las características de A se heredan como

privadas

Los tipos no son compatibles.

No se permiten hacer asignaciones polimórficas

Es la opción por defecto
Se puede mantener el nivel de visibilidad
original calificando la rutina en el bloque
public o protected

Útil para la herencia de implementación
Heredar de una clase sólo para reutilizar la

implementación

Tema 3

Herencia

8

Constructor de Depósito Estructurado

Los constructores no se heredan (= Java)
El constructor de la clase hija (clase derivada)
siempre tiene que invocar al constructor de la
clase padre (clase base)

DepositoEstructurado::DepositoEstructurado(Persona titular,
double capital, int plazoDias, double tipoInteres, double
tipoInteresVariable, double capitalVariable):Deposito(titular,
capital, plazoDias, tipoInteres){

this.tipoInteresVariable = tipoInteresVariable;
this.capitalVariable = capitalVariable;

}

Tema 3

Herencia

9

Redefinición de métodos

La clase padre debe indicar que los métodos se pueden

redefinir utilizando el modificador virtual
¿Viola el Principio de Abierto-Cerrado?

Un método en la clase hija que tenga la misma

signatura que un método virtual significa que lo está
redefiniendo
En la definición de la clase hija (fichero cabecera) hay

que incluir los métodos que se redefinen

Para invocar la ejecución de la versión de uno de los

métodos de cualquier otra clase se utiliza la calificación
de rutinas
NombreClase::nombreMétodo
Despotio::getCapital();

Tema 3

Herencia

10

Redefinición de métodos
class Deposito {
private:

public:

Persona* titular;
double capital;
int plazoDias;
double tipoInteres;
Deposito(…);
double liquidar();
virtual double getIntereses();
virtual double getCapital();
int getPlazoDias();
double getTipoInteres();
Persona* getTitular();

};

Tema 3

Herencia

11

Redefinición de métodos

Métodos redefinidos en DepositoEstructurado
//Override
double DepositoEstructurado::getIntereses() {

return Deposito::getIntereses() + getInteresesVariable();

}

//Override
double DepositoEstructurado::getCapital() {

return Deposito::getCapital() + getCapitalVariable();

}

Invocan a las versiones definidas en la clase Deposito

Tema 3

Herencia

12

Polimorfismo y Ligadura dinámica

El polimorfismo de asignaciónestá permitido para

entidades con semántica por valor y referencia.

Sólo se consideran que dos métodos están

sobrecargados (polimorfismo ad-hoc) si se definen
dentro del mismo ámbito
Una función de la clase hija con el mismo nombre que una

función heredada con distinta signatura la oculta.

Ligadura dinámica:

Sólo es posible para métodos virtuales.
La entidad polimórfica debe ser de tipo referencia.

Ligadura estática:

Se aplica la versión del método asociada al tipo estático de la

variable.

Tema 3

Herencia

13

Asignaciones polimórficas

Deposito deposito(…);
DepositoEstructurado de(…);

//Asignación polimórfica entre objetos valor
deposito = de;
//Ligadura estática, Deposito::getCapital
cout<<"Capital total "<<deposito.getCapital()<<endl;
Deposito* ptrDeposito = new Deposito(…);
DepositoEstructurado* ptrDe = new DepositoEstructurado(…);

//Asignación polimórfica de punteros
ptrDeposito = ptrDe;
//Ligadura dinámica, DepositoEstructurado::getCapital
cout<<"Capital total "<<ptrDeposito->getCapital()<<endl;
ptrDesposito->liquidar(); //Ligadura estática

Herencia

Tema 3

14

Sobrecarga en C++
class Deposito {

public:

virtual double getCapital();

};
class DepositoEstructurado: public Deposito{

public:

double getCapital(bool tipo);

};

getCapital está definido en distinto ámbito
getCapital no está sobrecargado en la clase

DepositoEstructurado

Tema 3

Herencia

15

Sobrecarga en C++
class Deposito {

public:

virtual double getCapital();

};
class DepositoEstructurado: public Deposito{

public:

double getCapital();
double getCapital(bool tipo);

};
getCapital está sobrecargado

La versión redefinida devuelve el capital total
La versión sobrecargada devuelve el capital fijo o variable en

función del parámetro

Tema 3

Herencia

16

Conversión de tipos
Operador dynamic_cast<Tipo*>(ptro)

Convierte el ptro en el puntero a Tipo
ptro debe ser una entidad polimórfica (su clase

debe tener algún método virtual)

La conversión se hace entre tipos compatibles
Si la conversión falla se le asigna cero (puntero

NULL)

También dynamic_cast<Tipo>(ref)

En caso de que la conversión no sea posible se lanza

una excepción (bad_cast)

Tema 3

Herencia

17

Conversión de tipos

Establecemos el tipo de interés variable a los

depósitos estructurados

Deposito** productos;
depositos = new Deposito*[MAX_DEPOSITOS];

DepositoEstructurado* depEst;

for (int i =0; i<MAX_DEPOSITOS; i++){

depEst = dynamic_cast<DepositoEstructurado*>(depositos[i]);
if (depEst != NULL)

depEst->setTipoInteresVariable(0.05);

}

Tema 3

Herencia

18

Consulta del tipo dinámico

Contamos el número de depósitos abiertos

int numDepositos = 0;

for (int i =0; i<MAX_PRODUCTOS; i++){

if (dynamic_cast<Deposito*>(productos[i]))

++numDepositos;

}

Equivalente a instanceof de Java

Tema 3

Herencia

19

Clases abstractas

ProductoFinanciero

titular

getImpuestos
getBeneficio

double getImpuestos() {
}

return getBeneficio() * 0.18;

Deposito

capital
plazoDias
tipoInteres

liquidar

getIntereses

Cuenta

saldo
ingreso
reintegro

getBeneficio es un

método abstracto

ProductoFinanciero

debe ser una clase
abstracta

Tema 3

Herencia

20

Clases abstractas

No existe una palabra reservada para indicar que una

clase es abstracta

Una clase es abstracta si contiene un método virtual

puro
class ProductoFinanciero{
private:
Persona* titular;
public:
ProductoFinanciero(Persona* titular);
virtual double getBeneficio()=0;
double getImpuestos();
Persona* getTitular();

};

Tema 3

Herencia

21

Interfaces

C++ no define el concepto de interfaz de

Java.

No es necesario, ya el lenguaje ofrece herencia

múltiple.
Si una clase quiere ser compatible con varios tipos,
basta con que herede públicamente de otras clases.

El equivalente a las interfaces de Java sería una

clase totalmente abstracta sólo con
métodos virtuales puros.

Tema 3

Herencia

22

Acciones

Para poder pasar una acción como parámetro

de una función podemos utilizar dos
estrategias:
Punteros a función:

En C++ es posible pasar una función como parámetro

Clase que represente la acción:

Definir una clase totalmente abstracta que simule la interfaz

de Java

Definir una subclase por cada acción que se necesite

implementar

Tema 3

Herencia

23

Acciones mediante punteros a función

Un puntero a función es una variable que
guarda la dirección de comienzo de la función

Puede considerarse como una especie de
“alias” de la función que hace que pueda
pasarse como parámetro a otras funciones
Las reglas del paso de parámetros se aplican

también para el paso de funciones como parámetro

X (*fptr) (A);

fptr es un puntero a función que recibe A como

argumento y devuelve X

Tema 3
  • Links de descarga
http://lwp-l.com/pdf2098

Comentarios de: Tema 3: Herencia en C++ (0)


No hay comentarios
 

Comentar...

Nombre
Correo (no se visualiza en la web)
Valoración
Comentarios...
CerrarCerrar
CerrarCerrar
Cerrar

Tienes que ser un usuario registrado para poder insertar imágenes, archivos y/o videos.

Puedes registrarte o validarte desde aquí.

Codigo
Negrita
Subrayado
Tachado
Cursiva
Insertar enlace
Imagen externa
Emoticon
Tabular
Centrar
Titulo
Linea
Disminuir
Aumentar
Vista preliminar
sonreir
dientes
lengua
guiño
enfadado
confundido
llorar
avergonzado
sorprendido
triste
sol
estrella
jarra
camara
taza de cafe
email
beso
bombilla
amor
mal
bien
Es necesario revisar y aceptar las políticas de privacidad