5 mecanismos reuntilizacion abstraccion

37
Mecanismos para la Reutilización y Abstracción del Código -1a parte Apoyo SSD5

Upload: uvm

Post on 03-Jul-2015

1.500 views

Category:

Documents


0 download

TRANSCRIPT

Page 1: 5 Mecanismos Reuntilizacion Abstraccion

Mecanismos para la Reutilización y Abstracción del Código -1a

parte

Apoyo SSD5

Page 2: 5 Mecanismos Reuntilizacion Abstraccion

Mtl Lourdes Cahuich 2

Objetivo

• Este módulo del curso presenta los mecanismos disponibles que facilitan la reutilización y abstracción del código en el lenguaje C++.

Page 3: 5 Mecanismos Reuntilizacion Abstraccion

5.1 Herencia

Page 4: 5 Mecanismos Reuntilizacion Abstraccion

Mtl Lourdes Cahuich 4

Un Mecanismo para la Abstracción y Reutilización del Código

• La herencia es un mecanismo en C++ (así como en Java) que facilita la reutilización y abstracción del código.

Page 5: 5 Mecanismos Reuntilizacion Abstraccion

Mtl Lourdes Cahuich 5

Herencia

• Al usar la herencia, se pueden construir clases nuevas basadas en clases viejas, permitiendo que las clases hijo compartan las funciones y datos miembro de la clase padre.

• A través de estas relaciones surgen las ventajas de la abstracción de datos (generalización y especialización).

Page 6: 5 Mecanismos Reuntilizacion Abstraccion

Mtl Lourdes Cahuich 6

Herencia

• En C++, una clase hijo hereda a todos los miembros no-privados de los datos incluyendo constructores.

• Una clase hijo en Java sin embargo, hereda de su clase padre a todos los miembros no-privados de los datos excepto constructores.

Page 7: 5 Mecanismos Reuntilizacion Abstraccion

Mtl Lourdes Cahuich 7

Herencia

• En ambos lenguajes, las clases hijo heredan todos los miembros no-privados de los datos

Page 8: 5 Mecanismos Reuntilizacion Abstraccion

Mtl Lourdes Cahuich 8

class BankAccount {protected:

double sum;string name;

public:BankAccount(string nm) : name(nm), sum(0) {}double balance() { return sum;}void deposit(double amount) {sum += amount;}void withdraw(double amount) {sum -= amount;}string get_name() { return name;}

};class SavingsAccount: public BankAccount {protected:

double rate;public:SavingsAccount(string nm)

: BankAccount(nm), // Call base class constructorrate(0.055) {}

void add_interest() {sum *= (1 + rate);}double get_rate() { return rate;}

};

Page 9: 5 Mecanismos Reuntilizacion Abstraccion

Mtl Lourdes Cahuich 9

Herencia

• El listado anterior es un ejemplo de la herencia en C++ que demuestra como invocar métodos de una clase padre.

• En este listado, hemos definido una clase SavingsAccount que hereda de la clase BankAccount.

Page 10: 5 Mecanismos Reuntilizacion Abstraccion

Mtl Lourdes Cahuich 10

Herencia

• La clase SavingsAccount provee una manera de añadir interés al dinero presentado en una cuenta

• La línea 23 invoca al constructor de la clase padre

• En C++ se usa el nombre de la clase padre seguida por los parámetros del constructor en paréntesis

Page 11: 5 Mecanismos Reuntilizacion Abstraccion

Mtl Lourdes Cahuich 11

Niveles de herencia

• C++ tiene tres tipos, o niveles, de herencia: pública, privada y protegida.

• La herencia pública es el tipo más común de herencia usado en C++.

• Todos los ejemplos que hemos visto hasta el momento usan la herencia pública para modelar la relación "es un..." de dos clases.

Page 12: 5 Mecanismos Reuntilizacion Abstraccion

Mtl Lourdes Cahuich 12

Niveles de herencia

• Las herencias privadas y protegidas modelan un tipo diferente de relación, llamada relación "usa un...".

• Para modelar que un carro usa un motor, podríamos heredar privadamente de la clase Engine al definir la clase Car.

Page 13: 5 Mecanismos Reuntilizacion Abstraccion

Mtl Lourdes Cahuich 13

Niveles de herencia

• La forma más apropiada de modelar esta relación, sería que nuestra clase Car contenga una instancia de la clase Engine

• Modelar la relación "usa un..." de esta forma, es conocido como composición.

• Todos los usos de herencia en este curso se enfocan en las relaciones de modelación "es un...".

Page 14: 5 Mecanismos Reuntilizacion Abstraccion

Polimorfismo

Page 15: 5 Mecanismos Reuntilizacion Abstraccion

Mtl Lourdes Cahuich 15

Un Mecanismo para Abstracción

• Una característica fundamental de los lenguajes de programación orientados a objetos es el polimorfismo.

• Polimorfismo es la capacidad de un objeto de tomar diversas formas

Page 16: 5 Mecanismos Reuntilizacion Abstraccion

Mtl Lourdes Cahuich 16

Polimorfismo

• En otras palabras, el polimorfismo permite que un programador se refiera a un objeto de una clase como un objeto de otra clase

• Esto tiene dos aplicaciones principales.

• Primero, podemos crear colecciones de objetos heterogéneos

Page 17: 5 Mecanismos Reuntilizacion Abstraccion

Mtl Lourdes Cahuich 17

Polimorfismo

• Podemos operar en los objetos individuales de estas colecciones como si fueran todos del mismo tipo, sin que los objetos pierdan sus identidades reales

• En segundo lugar, podemos codificar algoritmos que hacen solamente suposiciones mínimas sobre los objetos que manipulan

Page 18: 5 Mecanismos Reuntilizacion Abstraccion

Mtl Lourdes Cahuich 18

Polimorfismo

• Esto puede permitir que un algoritmo continúe funcionando correctamente aún cuando un programador introduce nuevas clases hijo en el sistema.

• Ambas aplicaciones ayudan a crear soluciones más duraderas

Page 19: 5 Mecanismos Reuntilizacion Abstraccion

Mtl Lourdes Cahuich 19

Polimorfismo en C++

• Los programadores se pueden referir a objetos de una manera que facilite soluciones elegantes

• En C++, utilizamos funciones virtualesen conjunto con los apuntadores para tener acceso a objetos polimórficos

Page 20: 5 Mecanismos Reuntilizacion Abstraccion

Mtl Lourdes Cahuich 20

Funciones virtuales

• Para ilustrar que funciones virtuales son y por que requerimos el uso de apuntadores en conjunto, veamos un ejemplo completo.

• Asume que deseamos implantar un sistema de gráficas que pueda desplegar varias formas geométricas en pantalla.

Page 21: 5 Mecanismos Reuntilizacion Abstraccion

Mtl Lourdes Cahuich 21

Funciones virtuales

• Es normal empezar con una jerarquía pequeña de gráficas de objetos.

class Shape { /* ... */ };

class Circle: public Shape { /* ... */ };

class Rectangle: public Shape { /* ... */ };

Page 22: 5 Mecanismos Reuntilizacion Abstraccion

Mtl Lourdes Cahuich 22

Funciones virtuales

• Supongamos que debemos tener la capacidad de mantener un registro de una colección de esa forma de objetos.

• Suponga que deseamos mantener un arreglo de formas de cualquier tipo.

• Podríamos intentar un arreglo del tipo Shape

Page 23: 5 Mecanismos Reuntilizacion Abstraccion

Mtl Lourdes Cahuich 23

Funciones virtuales

• Esto es razonable, puesto que es legítimo hacer una asignación de una clase hija a una variable de la clase base.

Circle C(3); // radius 3

Shape S[10];

S[0] = C; // syntactically correct, but ...

Page 24: 5 Mecanismos Reuntilizacion Abstraccion

Mtl Lourdes Cahuich 24

Funciones virtuales

• Desafortunadamente, las partes adicionales de la clase hija son simplemente "desnudadas" durante la tarea.

• Esto se conoce como el problema de las rebanadas o slicing problem.

• Perdemos a todos los miembros adicionales de los datos de la clase hija.

Page 25: 5 Mecanismos Reuntilizacion Abstraccion

Mtl Lourdes Cahuich 25

Funciones virtuales

• El rebanar, sin embargo, no ocurre cuando tratamos con los apuntadores.

• Por lo tanto, podemos salvar nuestro proyecto usando un arreglo de apuntadores a las formas.

Page 26: 5 Mecanismos Reuntilizacion Abstraccion

Mtl Lourdes Cahuich 26

Shape *layout[10];

layout[0] = new Circle(3);//radius 3

layout[1] = new Rectangle(2, 4);

// width 2, height 4

Page 27: 5 Mecanismos Reuntilizacion Abstraccion

Mtl Lourdes Cahuich 27

Funciones virtuales

• En seguida, necesitamos la clase Circle y Rectangle para reemplazar el método heredado del area()para proporcionar los detalles específicos sobre como calcular sus áreas respectivas.

• Una vez hecho esto, podemos intentar lo siguiente.

Page 28: 5 Mecanismos Reuntilizacion Abstraccion

Mtl Lourdes Cahuich 28

cout << layout[0]->area() << endl; // prints 0

cout << layout[1]->area() << endl;

// prints 0

Page 29: 5 Mecanismos Reuntilizacion Abstraccion

Mtl Lourdes Cahuich 29

Funciones virtuales

• El problema es que el tipo estático de layout[0] es Shape* y, por lo tanto, el método area() que pertenece a la clase Shape se invoca, en lugar del método específico area() para cada uno de esos objetos del arreglo

Page 30: 5 Mecanismos Reuntilizacion Abstraccion

Mtl Lourdes Cahuich 30

Funciones virtuales

• Lo que necesitamos es un mecanismo que revise el tipo dinámico de layout[0], por ejemplo, determina que es Circle*, y después llama al método del area() de la clase Circle.

• Esto se logra en C++ usando funciones virtuales

Page 31: 5 Mecanismos Reuntilizacion Abstraccion

Mtl Lourdes Cahuich 31

• La redefinición apropiada de la clase Shape, particularmente su método area().

• El método area() en las clases hijas no necesita ser redefinido (aunque es bien visto asociar la palabra reservada virtual a esos métodos).

Page 32: 5 Mecanismos Reuntilizacion Abstraccion

Mtl Lourdes Cahuich 32

class Shape {private: /* ... */public:

virtual float area(void) { return 0;}

/* ... */};

Page 33: 5 Mecanismos Reuntilizacion Abstraccion

Mtl Lourdes Cahuich 33

Funciones virtuales

• Asumiendo que Circle y Rectangleprovean su propio método area()reemplazando el que está en Shape, obtenemos la salida correcta.

cout << layout[0]->area() << endl;

// prints 28.2743

cout << layout[1]->area() << endl;

// prints 8

Page 34: 5 Mecanismos Reuntilizacion Abstraccion

Mtl Lourdes Cahuich 34

Funciones virtuales puras

• También pudimos modificar Shapehaciendo area()no sólo virtual sino también indefinida totalmente.

• Una función de este tipo es llamada una función virtual pura.

Page 35: 5 Mecanismos Reuntilizacion Abstraccion

Mtl Lourdes Cahuich 35

class Shape {

private:

/* ... */

public:

virtual float area(void) = 0;

// totally undefined

/* ... */

};

Page 36: 5 Mecanismos Reuntilizacion Abstraccion

Mtl Lourdes Cahuich 36

Clase abstracta

• Una clase que contiene una función virtual pura se conoce como clase abstracta. Implantaciones en C++ solamente usan clases abstractas en conjunto con herencia.

• En otras palabras, los programadores nunca crean instancias de clases abstractas.

Page 37: 5 Mecanismos Reuntilizacion Abstraccion

Mtl Lourdes Cahuich 37

Clase abstracta

• Existen simplemente para especificar la interfaz común de las clases hijas y para tener acceso a estas clases hijas polimórficas.

• En resumen, para obtener un comportamiento polimórfico, necesitamos:– usar apuntadores en lugar de objetos directos debido al rebanado

– declarar funciones miembro virtuales