SlideShare ist ein Scribd-Unternehmen logo
1 von 64
Downloaden Sie, um offline zu lesen
Programación Avanzada - Tema 3: Programación orientada a objetos

               http://www3.uji.es/~llopis/II17

                     José Luis Llopis Borrás

                     15 de noviembre de 2004
Índice

1. Introducción                                                                          4
  1.1. La herencia en el mundo real     . . . . . . . . . . . . . . . . . . . . . . .    5
  1.2. La herencia y la teoría de conjuntos . . . . . . . . . . . . . . . . . . . .      6
  1.3. El principio de los subtipos . . . . . . . . . . . . . . . . . . . . . . . . .    7

2. La herencia en la POO                                                                 8
  2.1. Jerarquía de clases    . . . . . . . . . . . . . . . . . . . . . . . . . . . .   10

3. Herencia pública en C++                                                              12
  3.1. Clases derivadas . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .     14
  3.2. Utilización de clases base y derivadas . . . . . . . . . . . . . . . . . . .     18
  3.3. El principio de los subtipos en C++    . . . . . . . . . . . . . . . . . . . .   20
  3.4. Acceso a los miembros de la clase base . . . . . . . . . . . . . . . . . .       21
  3.5. Miembros protegidos en la clase base . . . . . . . . . . . . . . . . . . .       22
  3.6. Redefinición de miembros de la clase base . . . . . . . . . . . . . . . .         25
  3.7. Herencia y constructores . . . . . . . . . . . . . . . . . . . . . . . . . .     31
3.8. Ligadura estática vs. dinámica . . . . . . . . . . . . . . . . . . . . . . .     42
   3.9. Funciones virtuales . . . . . . . . . . . . . . . . . . . . . . . . . . . . .    44
        3.9.1. Invocación de funciones virtuales a través de un puntero . . . . .        45
        3.9.2. Invocación de funciones virtuales a través de una referencia . . .        47

4. Caso práctico: aplicación gráfica                                                      49
   4.1. Identificación de objetos . . . . . . . . . . . . . . . . . . . . . . . . . .     50
   4.2. Diseño de la jerarquía de clases . . . . . . . . . . . . . . . . . . . . . .     51
   4.3. Diseño de la clase base . . . . . . . . . . . . . . . . . . . . . . . . . .      52
   4.4. Diseño de las subclases . . . . . . . . . . . . . . . . . . . . . . . . . .      53
   4.5. Estructura de datos heterogénea      . . . . . . . . . . . . . . . . . . . . .   55
   4.6. Operaciones globales . . . . . . . . . . . . . . . . . . . . . . . . . . .       56
   4.7. Ligadura estática . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .    57
   4.8. Funciones virtuales . . . . . . . . . . . . . . . . . . . . . . . . . . . . .    58
   4.9. Ligadura dinámica . . . . . . . . . . . . . . . . . . . . . . . . . . . . .      59
   4.10.Clases abstractas    . . . . . . . . . . . . . . . . . . . . . . . . . . . . .   62
   4.11.Conclusiones del caso práctico     . . . . . . . . . . . . . . . . . . . . . .   63
1 Introducción
  ® Los seres humanos realizamos abstracciones de acuerdo con dos tipos de
        relaciones: parte-de y tipo-de.
        µ Decimos que un león tiene cuatro patas, cola larga, dientes y uñas fuertes, etc.
        µ Pero, seguramente, como mejor definimos un león es diciendo que es-un tipo
             de mamífero carnívoro, concretamente un gran felino.

  ® En el ámbito de los lenguajes de programación hasta ahora sólo disponíamos de
        una herramienta para expresar el primer tipo de relaciones:
        µ La composición: permite expresar relaciones parte-de (o tiene-un). Los
             registros de C no son más que eso, una herramienta de composición.

  ® La programación orientada a objetos introduce una nueva herramienta para
        expresar el segundo tipo de relaciones:
        µ La herencia: permite expresar las relaciones tipo-de (o es-un).
Programación Avanzada - Tema 3: Programación orientada a objetos – 4
1.1 La herencia en el mundo real

  ® En el ejemplo siguiente, establecemos una organización jerárquica de distintos
        tipos de animales:
        µ Un león es un mamífero.
        µ Un león es un subtipo del tipo mamífero.
        µ El tipo mamífero es un supertipo de los tipos Gato y León.

                                                                                 Animal

                              Tipo
                            Categoría

                                                               Mamífero                            Ave

                           Subtipo
                         Subcategoría

                                                       Gato               León            Águila         Paloma




Programación Avanzada - Tema 3: Programación orientada a objetos – 5
1.2 La herencia y la teoría de conjuntos

  ® El conjunto de elementos que pertenecen a un tipo incluye a los elementos que
        pertenezcan a sus subtipos.

                Animal

                   Mamífero                               Ave                      Conjuntos anidados
                    Gato              León                 Águila      Paloma      Relación entre tipos y subtipos




                             Edificio                Motocicleta       Conjuntos disjuntos
                                                                       No hay relación de subtipado
                                                                       entre estos tipos




Programación Avanzada - Tema 3: Programación orientada a objetos – 6
1.3 El principio de los subtipos

  ® Principio de subtipos: “Un objeto de un subtipo puede aparecer en cualquier
        lugar donde se espera que aparezca un objeto del supertipo”.
        µ Los animales son capaces de moverse por sí mismos.
        µ Los mamíferos son capaces de moverse por sí mismos.
        µ Las aves son capaces de moverse por sí mismas.
        µ Los gatos son capaces de moverse por sí mismos.

  ® A la inversa no es cierto.
        µ Los gatos maullan.
        µ ¿Los mamíferos maullan?
        µ ¿Los animales maullan?



Programación Avanzada - Tema 3: Programación orientada a objetos – 7
2 La herencia en la POO
  ® La herencia es un recurso fundamental en los lenguajes orientados a objetos.

  ® Esencialmente consiste en definir una nueva clase:
        µ como extensión de otra previamente definida, y
        µ sin modificar la ya existente.

  ® La nueva clase hereda de la clase base:
        µ los atributos (variables miembro de la clase), y
        µ los métodos (funciones miembro de la clase).

  ® Principal beneficio: la reutilización del código.
        µ Ahorro de esfuerzo.
        µ Mayor confianza en el código.


Programación Avanzada - Tema 3: Programación orientada a objetos – 8
2 La herencia en la POO (II)
  ® La clase derivada es-un tipo especial de clase base.
        µ Un Mecánico es-un (tipo especial de) Empleado.
        µ Un Comercial es-un (tipo especial de) Empleado.

               Clase
               base                                  Empleado
             superclase
                                                                               Empleado
                                                                                Mecánico   Comercial
               Clase
              derivada                   Mecánico                  Comercial
              subclase




Programación Avanzada - Tema 3: Programación orientada a objetos – 9
2.1 Jerarquía de clases

  ® La herencia permite
        establecer jerarquías de
        clases relacionadas entre sí.
                                                                                         Empleado
                                                                                  sueldoFijo
  ® En el ejemplo, las subclases
                                                                                  asignarSueldo(s)
        heredan los datos y las                                                   sueldoBase()

        operaciones de la clase
        base.                                                               Mecanico                          Comercial
                                                                   numPiezas                         ventas
  ® Los objetos de una clase                                       precioPorPieza
        derivada pueden acceder a                                  asignarNumPrecio(n, p)            asignarVentas(v)
                                                                   sueldo()                          sueldo()
        los miembros públicos
        heredados de la clase base                                                          (Versión 1)

        de igual forma que acceden
        a los propios.

Programación Avanzada - Tema 3: Programación orientada a objetos – 10
2.1 Jerarquía de clases (II)

  ® Un objeto m de la clase Mecanico es además un Empleado, por tanto contiene
        todos los miembros de la clase base (ya sean datos o funciones) y además los
        propios miembros definidos en la clase derivada.

                                                                        Objeto m
                      propia heredada
                     Interfaz Interfaz




                                            asignarSueldo(s)
                                                                            sueldoFijo   Dato
                                             sueldoBase()                                heredado

                                                                            numPiezas
                                         asignarNumPrecio(n, p)                          Datos
                                                                        precioPorPieza   propios
                                                sueldo()




Programación Avanzada - Tema 3: Programación orientada a objetos – 11
3 Herencia pública en C++
  ® Vamos a realizar la implementación completa de la jerarquía formada por las
    clases Empleado, Mecanico y Comercial. Comenzamos con la clase base.

                                                        empleado.h (versión 1)
 # i f n d e f EMPLEADO_H
 # define EMPLEADO_H


 class Empleado {
 private :
      float     sueldoFijo ;
 public :
      void      a s i gn ar S ue ld o ( f l o a t ) ;
      float     sueldoBase ( ) const ;
 };


 #endif




Programación Avanzada - Tema 3: Programación orientada a objetos – 12
3 Herencia pública en C++ (II)
  ® La implementación de la clase base no presenta ninguna particularidad:

                                                     empleado.cpp (versión 1)
 # include "empleado.h"


 void Empleado : : as ig na r Su el d o ( f l o a t s ) {
     sueldoFijo = s ;
 }


 f l o a t Empleado : : sueldoBase ( ) const {
     return sue ldoFi jo ;
 }




Programación Avanzada - Tema 3: Programación orientada a objetos – 13
3.1 Clases derivadas

  ® Un mecánico es-un tipo especial de
        empleado, por lo tanto, definimos la                                            mecanico.h (versión 1)
        clase Mecanico como una subclase                                # i f n d e f MECANICO_H
                                                                        # define MECANICO_H
        de Empleado.

  ® En C++ expresamos esta relación                                     # include "empleado.h"

        utilizando herencia pública. También                            class Mecanico : public Empleado {
        es posible utilizar otros tipos de                              private :
                                                                             int    numPiezas ;
        herencia, pero sólo la herencia
                                                                             f l o a t precioPorPieza ;
        pública expresa la relación es-un.                              public :
                                                                             void    asignarNumPrecio ( i n t , f l o a t ) ;
  ® Con la herencia pública cada                                             f l o a t sueldo ( ) const ;
        miembro de la clase base es                                     };

        heredado en la subclase                                         #endif
        manteniendo sus privilegios de
        acceso.
Programación Avanzada - Tema 3: Programación orientada a objetos – 14
3.1 Clases derivadas (II)

  ® En la implementación de la subclase Mecanico podemos utilizar cualquier
    miembro público de la clase base (p.e. sueldoBase()).

  ® Cuando el compilador encuentra la llamada a la función sueldoBase() primero
    busca la función en la clase Mecanico y, como no existe, la busca en la clase base.

                                                      mecanico.cpp (versión 1)
 # include "mecanico.h"


 void Mecanico : : asignarNumPrecio ( i n t n , f l o a t p ) {
     numPiezas = n ;
     precioPorPieza = p ;
 }


 f l o a t Mecanico : : sueldo ( ) const {
     f l o a t complementos = numPiezas ∗ p r e c i o P o r P i e z a ;
     r e t u r n sueldoBase ( ) + complementos ;
 }


Programación Avanzada - Tema 3: Programación orientada a objetos – 15
3.1 Clases derivadas (III)

  ® Un comercial es-un tipo especial de empleado, por lo tanto, definimos la clase
    Comercial como una subclase de Empleado.

                                                        comercial.h (versión 1)
 # i f n d e f COMERCIAL_H
 # define COMERCIAL_H


 # include "empleado.h"


 class Comercial : public Empleado {
 private :
      f l o a t ventas ;
 public :
      void     a si gn ar V en ta s ( f l o a t ) ;
      f l o a t sueldo ( ) const ;
 };


 # e n d i f COMERCIAL


Programación Avanzada - Tema 3: Programación orientada a objetos – 16
3.1 Clases derivadas (IV)

  ® Por último, implementamos la clase Comercial.

  ® De nuevo, desde una función miembro de la clase Comercial, podemos llamar a
    una función de la clase base: un Comercial no deja de ser al mismo tiempo un
    Empleado.

                                                     comercial.cpp (versión 1)
 # include "comercial.h"


 void Comercial : : as ig n ar Ve nt a s ( f l o a t v ) {
     ventas = v ;
 }


 f l o a t Comercial : : sueldo ( ) const {
     f l o a t complementos = ventas ∗ 0 . 1 0 ;
     r e t u r n sueldoBase ( ) + complementos ;
 }


Programación Avanzada - Tema 3: Programación orientada a objetos – 17
3.2 Utilización de clases base y derivadas

                                                           test.cpp (versión 1)
 # include < iostream >
 # include "empleado.h"
 # include "mecanico.h"
 # include "comercial.h"
 using namespace s t d ;


 void f ( Empleado e ) {
     c o u t < < "Desde f() e.sueldoBase() = " < < e . sueldoBase ( ) < < e n d l ;
 }


 i n t main ( ) {
     Empleado e ;
     e . as ig na r Su el d o ( 1 0 0 0 ) ;
     c o u t < < "Sueldo del empleado:                  " < < e . sueldoBase ( ) < < e n d l ;

     Mecanico m;
     m. a s i gn a r S ue l do ( 2 0 0 0 ) ;
     m. asignarNumPrecio ( 1 0 0 , 3 ) ;
     c o u t < < "Sueldo del mecánico:                  " < < m. sueldo ( ) < < e n d l ;
Programación Avanzada - Tema 3: Programación orientada a objetos – 18
3.2 Utilización de clases base y derivadas


     Comercial c ;
     c . as ig na r Su el do ( 3 0 0 0 ) ;
     c . as ig na r Ve nt as ( 2 0 0 0 ) ;
     c o u t < < "Sueldo del comercial: " < < c . sueldo ( ) < < e n d l ;


     f (e) ;
     f (m) ;
     f (c) ;
 }



                                                            salida (versión 1)
 Sueldo d e l empleado :               1000
 Sueldo d e l mecánico :               2300
 Sueldo d e l c o m e r c i a l : 3 2 0 0
 Desde f ( ) e . sueldoBase ( ) = 1 0 0 0
 Desde f ( ) e . sueldoBase ( ) = 2 0 0 0
 Desde f ( ) e . sueldoBase ( ) = 3 0 0 0


Programación Avanzada - Tema 3: Programación orientada a objetos – 19
3.3 El principio de los subtipos en C++

  ® El principio de los subtipos puede enunciarse de nuevo para C++ de la manera
        siguiente:
                 Una clase derivada puede aparecer en cualquier lugar donde se
             espera una clase base pública.

  ® Efectivamente: la función f() de test.cpp está definida para recibir objetos de la
    clase Empleado. Sin embargo, también podemos llamarla con objetos de las
    clases Mecánico y Comercial.

  ® En todo caso, desde dentro de la función f() sólo podemos acceder a los
        miembros públicos de la clase base. La siguiente implementación de la función
        f() es incorrecta puesto que sueldo() no es una función de la clase Empleado:
        void f ( Empleado e ) { / / i n c o r r e c t o
            c o u t < < "Desde f() e.sueldo() = " < < e . sueldo ( ) < < e n d l ;
        }


Programación Avanzada - Tema 3: Programación orientada a objetos – 20
3.4 Acceso a los miembros de la clase base

  ® Hemos dicho que la clase derivada hereda todos los miembros de la clase base,
        pero ¿qué ocurre con los niveles de acceso?
        µ private Los miembros privados de la clase base no son accesibles en la clase
             derivada (ni en el exterior).
        µ public Los miembros públicos de la clase base son accesibles desde la clase
             derivada (y desde el exterior).

  ® Disponemos, además, de un nivel intermedio:
        µ protected Los miembros protegidos en la clase base:
            ª son accesibles en la clase derivada.
            ª no son accesibles desde el exterior.
                                                                         Recuerda que estamos hablando
                                                                        en el ámbito de la herencia pública.

Programación Avanzada - Tema 3: Programación orientada a objetos – 21
3.5 Miembros protegidos en la clase base

  ® La función sueldo() de las clases Mecanico y Comercial invoca a la función
    sueldoBase() de la clase Empleado para averiguar cuál es el sueldo fijo del
        empleado. Lo hacemos así porque no podemos acceder al dato privado
        sueldoFijo de la clase base.

  ® Pero, ¿y si sueldoFijo en lugar de privado fuera protegido? En ese caso:
        µ sería accesible desde la función sueldo() de las subclases,
        µ y, al mismo tiempo, se mantendría inaccesible desde el exterior.




Programación Avanzada - Tema 3: Programación orientada a objetos – 22
3.5 Miembros protegidos en la clase base (II)

  ® Declaramos el miembro sueldoFijo como protected:

                                                     empleado.h (versión 1 bis)
        # i f n d e f EMPLEADO_H
        # define EMPLEADO_H


        class Empleado {
        protected :
             float     sueldoFijo ;
        public :
             void      a si gn ar S ue ld o ( f l o a t ) ;
             float     sueldoBase ( ) const ;
        };


        #endif




Programación Avanzada - Tema 3: Programación orientada a objetos – 23
3.5 Miembros protegidos en la clase base (III)

  ® Ahora, sueldoFijo es accesible desde las clases derivadas:

                                                     mecanico.cpp (versión 1 bis)
        ...
        f l o a t Mecanico : : sueldo ( ) const {
            f l o a t complementos = numPiezas ∗ p r e c i o P o r P i e z a ;
            r e t u r n s u e l d o F i j o + complementos ;
        }



  ® ... aunque sigue siendo inaccesible desde el exterior:

                                                          test.cpp (versión 1 bis)
        i n t main ( ) {
            ...
            Mecanico m;
            ...
            c o u t   m. s u e l d o F i j o ; / / i n c o r r e c t o
        }


Programación Avanzada - Tema 3: Programación orientada a objetos – 24
3.6 Redefinición de miembros de la clase base

  ® La función sueldoBase()
    de la clase Empleado y las
    funciones sueldo() de las                                                           Empleado
                                                                                  sueldoFijo
        subclases tienen el mismo
                                                                                  asignarSueldo(s)
        objetivo: devolver el sueldo                                              sueldoBase()
                                                                                  sueldo()
        de una persona. No hay
        ninguna razón para que
        tengan nombres diferentes.                                         Mecanico                       Comercial
                                                                    numPiezas                    ventas
  ® Si usamos el mismo                                              precioPorPieza
                                                                    asignarNumPrecio(n, p)       asignarVentas(v)
        nombre, conseguiremos                                       sueldo()                     sueldo()
        uniformizar la interfaz de las
                                                                                        (Versión 2)
        tres clases, facilitando su
        uso.

Programación Avanzada - Tema 3: Programación orientada a objetos – 25
3.6 Redefinición de miembros de la clase base (II)

  ® Partiendo de la versión 1 (en la que no hay miembros protegidos), cambiamos el
    nombre de la función sueldoBase() por sueldo() en la clase base:

                                                        empleado.h (versión 2)
        class Empleado {
        private :
             float     sueldoFijo ;
        public :
             void      a si gn ar S ue ld o ( f l o a t ) ;
             float     sueldo ( ) const ;
        };



                                                      empleado.cpp (versión 2)
        ...
        f l o a t Empleado : : sueldo ( ) const {
             return sue ldoFij o ;
        }


Programación Avanzada - Tema 3: Programación orientada a objetos – 26
3.6 Redefinición de miembros de la clase base (III)

  ® Al implementar las subclases, redefinimos la función sueldo() con un código
        diferente al que tenía en la clase base. Estamos ante una forma de sobrecarga de
        funciones.

  ® Ahora la función sueldo() de las subclases debe llamar a la función sueldo() de
        la clase base, pero como tiene el mismo nombre, hay que utilizar el operador de
        resolución de ámbito: Empleado::sueldo().

                                                      mecanico.cpp (versión 2)
        ...
        f l o a t Mecanico : : sueldo ( ) const {
            f l o a t complementos = numPiezas ∗ p r e c i o P o r P i e z a ;
            r e t u r n Empleado : : sueldo ( ) + complementos ;
        }


        µ El mismo cambio lo realizamos también en la clase Comercial.

Programación Avanzada - Tema 3: Programación orientada a objetos – 27
3.6 Redefinición de miembros de la clase base (IV)

                                                           test.cpp (versión 2)
 # include  iostream 
 # include empleado.h
 # include mecanico.h
 # include comercial.h
 using namespace s t d ;


 void f ( Empleado e ) {
     c o u t   Desde f() e.sueldo() =    e . sueldo ( )   e n d l ;
 }


 i n t main ( ) {
     Empleado e ;
     e . as ig na r Su el d o ( 1 0 0 0 ) ;
     c o u t   Sueldo del empleado:                     e . sueldo ( )   e n d l ;

     Mecanico m;
     m. a s i gn a r S ue l do ( 2 0 0 0 ) ;
     m. asignarNumPrecio ( 1 0 0 , 3 ) ;
     c o u t   Sueldo del mecánico:                     m. sueldo ( )   e n d l ;
Programación Avanzada - Tema 3: Programación orientada a objetos – 28
3.6 Redefinición de miembros de la clase base (IV)


     Comercial c ;
     c . as ig na r Su el d o ( 3 0 0 0 ) ;
     c . as ig na r Ve nt a s ( 2 0 0 0 ) ;
     c o u t   Sueldo del comercial:    c . sueldo ( )   e n d l ;


     f (e) ;
     f (m) ;
     f (c) ;
 }



                                                            salida (versión 2)
 Sueldo d e l empleado :                1000
 Sueldo d e l mecánico :                2300
 Sueldo d e l c o m e r c i a l : 3 2 0 0
 Desde f ( ) e . sueldo ( ) = 1 0 0 0
 Desde f ( ) e . sueldo ( ) = 2 0 0 0
 Desde f ( ) e . sueldo ( ) = 3 0 0 0


Programación Avanzada - Tema 3: Programación orientada a objetos – 29
3.6 Redefinición de miembros de la clase base (V)

  ® En el archivo test.cpp podemos apreciar la uniformidad de la interfaz de las
        clases: calculamos el sueldo de la misma forma para objetos de los tipos
        Empleado, Mecanico y Comercial.

  ® Observa que cuando un objeto de una clase derivada invoca a la función
    sueldo(), el compilador elige la versión local, es decir, la de la clase derivada y
        no la de la clase base.
        µ Decimos que la función Mecanico::sueldo() oculta la función
          Empleado::sueldo().
        i n t main ( ) {
            Mecanico m;
            ...
            m. sueldo ( ) ; / / siempre se e j e c u t a l a f u n c i ó n de l a c l a s e Mecanico
                                / / y nunca l a de l a c l a s e Empleado
        }


Programación Avanzada - Tema 3: Programación orientada a objetos – 30
3.7 Herencia y constructores

  ® Las clases que intervienen en una relación de herencia pueden contener
        constructores y destructores.

  ® Al declarar un objeto de una clase derivada, se ejecuta de forma automática:
        µ Primero: el constructor de la clase base.
        µ Segundo: el constructor de la clase derivada.
  ® Cuando un objeto de una clase derivada deja de existir (si es estático, porque el
        ámbito donde fue declarado ha acabado, y si es dinámico, porque se evalúa el
        operador delete) se ejecuta de forma automática:
        µ Primero: el destructor de la clase derivada.
        µ Segundo: el destructor de la clase base.
  ® Si el constructor de la clase base necesita argumentos para poder ejecutarse
        éstos deben ser facilitados por el constructor de la clase derivada a través de una
        lista de inicialización.
Programación Avanzada - Tema 3: Programación orientada a objetos – 31
3.7 Herencia y constructores (II)

  ® Partiendo de la versión 2, añadimos
        constructores a nuestras clases.

  ® Aprovechamos la ocasión para                                                               Empleado
                                                                                       nombre
        incorporar a la clase base el nombre                                           sueldoFijo
                                                                                       Empleado(n, s)
        del empleado y el operador de salida.                                          sueldo()
                                                                                       operator(canal, emp)
  ® Para simplificar el código,
        eliminamos las funciones
                                                                                Mecanico                         Comercial
        Empleado::asignarSueldo(),                                      numPiezas                       ventas
                                                                        precioPorPieza
        Mecanico::asignarNumPrecio()                                    Mecanico(n, s, num, pre)        Comercial(n, s, v)
                                                                        sueldo()                        sueldo()
        y Comercial::asignarVentas().
                                                                                               (Versión 3)




Programación Avanzada - Tema 3: Programación orientada a objetos – 32
3.7 Herencia y constructores (III)

                                                       empleado.h (versión 3)
 # i f n d e f EMPLEADO_H
 # define EMPLEADO_H


 # include  iostream 
 # include  s t r i n g 
 using namespace s t d ;


 class Empleado {
 private :
      s t r i n g nombre ;
      float      sueldoFijo ;
 public :
      Empleado ( s t r i n g , f l o a t ) ;
      f l o a t sueldo ( ) const ;
      f r i e n d ostream  operator  ( ostream  , Empleado ) ;
 };


 #endif

Programación Avanzada - Tema 3: Programación orientada a objetos – 33
3.7 Herencia y constructores (IV)

                                                     empleado.cpp (versión 3)
 # include empleado.h
 # include  iostream 
 # include  s t r i n g 
 using namespace s t d ;


 Empleado : : Empleado ( s t r i n g n , f l o a t s )
 : nombre ( n ) , s u e l d o F i j o ( s )
 { }


 f l o a t Empleado : : sueldo ( ) const {
     return sue ldoFi jo ;
 }


 ostream  operator  ( ostream  canal , Empleado e ) {
     c a n a l   e . nombre ;
     return canal ;
 }



Programación Avanzada - Tema 3: Programación orientada a objetos – 34
3.7 Herencia y constructores (V)

                                                        mecanico.h (versión 3)
 # i f n d e f MECANICO_H
 # define MECANICO_H


 # include empleado.h
 # include  s t r i n g 
 using namespace s t d ;


 class Mecanico : public Empleado {
 private :
      int      numPiezas ;
      f l o a t precioPorPieza ;
 public :
      Mecanico ( s t r i n g , f l o a t , i n t , f l o a t ) ;
      f l o a t sueldo ( ) const ; / / o c u l t a Empleado : : sueldo ( )
 };


 #endif



Programación Avanzada - Tema 3: Programación orientada a objetos – 35
3.7 Herencia y constructores (VI)

                                                      mecanico.cpp (versión 3)
 # include empleado.h
 # include mecanico.h
 # include  s t r i n g 
 using namespace s t d ;


 Mecanico : : Mecanico ( s t r i n g n , f l o a t s , i n t piezas , f l o a t p r e c i o )
 : Empleado ( n , s ) , numPiezas ( p i e z a s ) , p r e c i o P o r P i e z a ( p r e c i o )
 { }


 f l o a t Mecanico : : sueldo ( ) const {
     f l o a t complementos = numPiezas ∗ p r e c i o P o r P i e z a ;
     r e t u r n Empleado : : sueldo ( ) + complementos ;
 }




Programación Avanzada - Tema 3: Programación orientada a objetos – 36
3.7 Herencia y constructores (VII)

                                                        comercial.h (versión 3)
 # i f n d e f COMERCIAL_H
 # define COMERCIAL_H


 # include empleado.h
 # include  s t r i n g 
 using namespace s t d ;


 class Comercial : public Empleado {
 private :
      f l o a t ventas ;
 public :
      Comercial ( s t r i n g , f l o a t , f l o a t ) ;
      f l o a t sueldo ( ) const ; / / o c u l t a Empleado : : sueldo ( )
 };


 #endif




Programación Avanzada - Tema 3: Programación orientada a objetos – 37
3.7 Herencia y constructores (VIII)

                                                     comercial.cpp (versión 3)
 # include comercial.h
 # include empleado.h
 # include  s t r i n g 
 using namespace s t d ;


 Comercial : : Comercial ( s t r i n g n , f l o a t s , f l o a t v )
 : Empleado ( n , s ) , ventas ( v )
 { }


 f l o a t Comercial : : sueldo ( ) const {
     f l o a t complementos = ventas ∗ 0 . 1 0 ;
     r e t u r n Empleado : : sueldo ( ) + complementos ;
 }




Programación Avanzada - Tema 3: Programación orientada a objetos – 38
3.7 Herencia y constructores (IX)

                                                           test.cpp (versión 3)
 # include empleado.h
 # include mecanico.h
 # include comercial.h


 # include  iostream 
 using namespace s t d ;


 void f ( Empleado e ) {
     c o u t   Desde f():  ;
     c o u t   Sueldo de    e   :                     e . sueldo ( )   e n d l ;
 }


 i n t main ( ) {
     Empleado e ( Maria , 1 0 0 0 ) ;
     c o u t   Sueldo de    e   :                     e . sueldo ( )   e n d l ;

     Mecanico m( Ramon , 2 0 0 0 , 1 0 0 , 3 ) ;
     c o u t   Sueldo de    m   :                     m. sueldo ( )   e n d l ;

Programación Avanzada - Tema 3: Programación orientada a objetos – 39
3.7 Herencia y constructores (IX)

     Comercial c ( Luisa , 3 0 0 0 , 2 0 0 0 ) ;
     c o u t   Sueldo de    c   :                     c . sueldo ( )   e n d l ;

     f (e) ;
     f (m) ;
     f (c) ;
 }



                                                            salida (versión 3)
 Sueldo de Maria :             1000
 Sueldo de Ramon :             2300
 Sueldo de L u i s a :         3200
 Desde f ( ) : Sueldo de Maria :                  1000
 Desde f ( ) : Sueldo de Ramon :                  2000
 Desde f ( ) : Sueldo de L u i s a :              3000




Programación Avanzada - Tema 3: Programación orientada a objetos – 40
3.7 Herencia y constructores (X)

 Observa que:

  ® Los constructores de las clases derivadas utilizan la lista de inicialización para
        pasar los argumentos que necesita el constructor de la clase base. Recuerda que
        primero se ejecuta automáticamente el constructor de la clase base y luego el de
        la derivada.




Programación Avanzada - Tema 3: Programación orientada a objetos – 41
3.8 Ligadura estática vs. dinámica

  ® Hemos pasado por alto un detalle importante: ¿por qué la salida de la ejecución
    del programa test.cpp muestra dos sueldos diferentes para Ramón y para Luisa?
        µ Cuando se calcula el sueldo de Ramón en la función main() con m.sueldo(),
          la función que se ejecuta es la de la clase Mecanico, puesto que m está
             declarado como un objeto de esa clase.
        µ Cuando se calcula el sueldo de Ramón en la función f() con e.sueldo() la
          función que se ejecuta es la de la clase Empleado, puesto que e está declarado
          como un objeto de esa clase, a pesar de que en ejecución el parámetro e
          recibe un objeto de la clase Mecanico.

  ® El problema radica en cómo decide el compilador qué función debe ejecutarse, es
        decir, cómo se liga la llamada de una función a su ejecución.




Programación Avanzada - Tema 3: Programación orientada a objetos – 42
3.8 Ligadura estática vs. dinámica (II)

  ® Existen dos tipos de ligadura:
        µ Ligadura estática: se produce cuando la llamada a una función de un objeto
             es evaluada según el tipo asociado explícitamente en la declaración del mismo.
            ª Esta es la ligadura que se utiliza por omisión en C y C++ y es la causa del
              comportamiento detectado en el programa test.cpp.
        µ Ligadura dinámica: se produce cuando la llamada a una función de un objeto
             es evaluada según el tipo asociado al objeto en tiempo de ejecución. Se conoce
             también como polimorfismo en tiempo de ejecución.
            ª En C++ este tipo de ligadura es empleada al llamar a cierto tipo de funciones
                 especiales, conocidas como funciones virtuales, solamente cuando la
                 llamada se hace a través de punteros o referencias.

                                     En la siguiente sección estudiaremos un caso práctico en el
                                    que la ligadura dinámica juega un papel fundamental.
Programación Avanzada - Tema 3: Programación orientada a objetos – 43
3.9 Funciones virtuales

  ® Deseamos que en nuestra jerarquía de
    clases Empleado, Mecanico y
    Comercial la función sueldo() sea
                                                                                                   Empleado
    invocada desde la función f()                                                       nombre
                                                                                        sueldoFijo
        utilizando ligadura dinámica. Para                                              Empleado(n, s)
                                                                                        virtual sueldo()
        ello debemos:                                                                   operator(canal, emp)


      1. Declarar como virtual la función
                                                                                Mecanico                             Comercial
             sueldo() en la clase base (sólo es                         numPiezas                           ventas
                                                                        precioPorPieza
             necesario hacerlo en la clase                              Mecanico(n, s, num, pre)            Comercial(n, s, v)
                                                                        sueldo()                            sueldo()
             base).
      2. Modificar la implementación de f()                                                         (Versión 4)


             para que la llamada a la función
             sueldo() se realice a través de un
             puntero o una referencia.
Programación Avanzada - Tema 3: Programación orientada a objetos – 44
3.9.1 Invocación de funciones virtuales a través de un puntero

                                                       empleado.h (versión 4)
 class Empleado {
      ...
      v i r t u a l f l o a t sueldo ( ) const ;
 };



                                                           test.cpp (versión 4)
 void f ( Empleado ∗ p t r _ e ) {
      c o u t   Desde f():  ;
      c o u t   Sueldo de    ( ∗ p t r _ e )   :                  p t r _ e −sueldo ( )   e n d l ;
 }


 i n t main ( ) {
      ...
      f (e ) ;
      f (m) ;
      f ( c ) ;
 }

Programación Avanzada - Tema 3: Programación orientada a objetos – 45
3.9.1 Invocación de funciones virtuales a través de un puntero (II)

                                                            salida (versión 4)
 Sueldo de Maria :             1000
 Sueldo de Ramon :             2300
 Sueldo de L u i s a :         3200
 Desde f ( ) : Sueldo de Maria :                  1000
 Desde f ( ) : Sueldo de Ramon :                  2300
 Desde f ( ) : Sueldo de L u i s a :              3200


  ® La función f() recibe como argumento un puntero a un objeto de la clase
    Empleado y a través de él llama a la función sueldo().
  ® Ante esta situación, el compilador retrasa la decisión de qué función sueldo()
        ejecutar hasta el momento de la ejecución.

  ® En cada una de las tres llamadas a la función f() se recibe como argumento un
    puntero a un objeto de tipo Empleado, Mecanico y Comercial respectivamente.
    En cada caso, ptr_e-sueldo() invoca la función sueldo() de la clase
        correspondiente.
Programación Avanzada - Tema 3: Programación orientada a objetos – 46
3.9.2 Invocación de funciones virtuales a través de una referencia

                                                       empleado.h (versión 5)
 class Empleado {
      ...
      v i r t u a l f l o a t sueldo ( ) const ;
 };



                                                           test.cpp (versión 5)
 void f ( Empleado  e ) {
      c o u t   Desde f():  ;
      c o u t   Sueldo de    e   :                    e . sueldo ( )   e n d l ;
 }


 i n t main ( ) {
      ...
      f (e) ;
      f (m) ;
      f (c) ;
 }

Programación Avanzada - Tema 3: Programación orientada a objetos – 47
3.9.2 Invocación de funciones virtuales a través de una referencia (II)

                                                            salida (versión 5)
 Sueldo de Maria :             1000
 Sueldo de Ramon :             2300
 Sueldo de L u i s a :         3200
 Desde f ( ) : Sueldo de Maria :                  1000
 Desde f ( ) : Sueldo de Ramon :                  2300
 Desde f ( ) : Sueldo de L u i s a :              3200



  ® La función f() recibe como argumento una referencia a un objeto de la clase
    Empleado y a través de ella llama a la función sueldo().

  ® Ante esta situación, el compilador retrasa la decisión de qué función sueldo()
        ejecutar hasta el momento de la ejecución.

  ® En cada una de las tres llamadas a la función f() se recibe como argumento un
    objeto de tipo Empleado, Mecanico y Comercial respectivamente. En cada caso,
    e.sueldo() invoca la función sueldo() de la clase correspondiente.
Programación Avanzada - Tema 3: Programación orientada a objetos – 48
4 Caso práctico: aplicación gráfica
 Como ejemplo de aplicación de la ligadura dinámica (o polimorfismo en tiempo de
 ejecución) estudiaremos un caso práctico: una aplicación gráfica.

  ® Diseño de la jerarquía de clases.

  ® Ligadura estática.

  ® Ligadura dinámica y polimorfismo.

  ® Clases abstractas.




Programación Avanzada - Tema 3: Programación orientada a objetos – 49
4.1 Identificación de objetos

  ® La aplicación gráfica debe manipular una
        serie de figuras como cuadrados, rectángulos,
        círculos, elipses, etc. Todos estos objetos se
        caracterizan por ciertos rasgos comunes:
        µ Atributos (datos)
         ª Coordenadas
         ª Color del fondo
         ª Color del borde
         ª Grosor del trazo
        µ Operaciones (funciones)
         ª Mover
         ª Dibujar
         ª Área
         ª Perímetro
Programación Avanzada - Tema 3: Programación orientada a objetos – 50
4.2 Diseño de la jerarquía de clases


                                                                           Figura
                                                                        x, y, fondo, borde
                                                                         mover, dibujar,
                                                                         área, perímetro




                                          Elipse                        Rectángulo                 Triángulo
                                     ejeMayor, ejeMenor                    base, altura                 vértices
                                          dibujar,                           dibujar,                  dibujar,
                                       área, perímetro                   área, perímetro            área, perímetro




                                        Círculo                          Cuadrado                Notación Booch
                                           radio                                             A                     B
                                      área, perímetro                   área, perímetro
                                                                                             Clase A hereda de clase B




Programación Avanzada - Tema 3: Programación orientada a objetos – 51
4.3 Diseño de la clase base

 class F i g u r a {
      Punto p o s i c i o n ;
      C o l o r fondo , borde ;
      // ...                                                                 Notación Booch
 public :                                                                A                     B
      F i g u r a ( Punto p , C o l o r c1 , C o l o r c2 ) ;              Clase A contiene
      void mover ( Punto           p) ;                                 una instancia de clase B
      void d i b u j a r ( ) const ;
      f l o a t area ( ) const ;                                                           1
                                                                                                   1       Punto
      f l o a t p e r i m e t r o ( ) const ;
      // ...
                                                                             Figura            1
 };
                                                                                                       2

 void F i g u r a : : mover ( Punto p ) {                                                                  Color
      posicion = p ;
 }




Programación Avanzada - Tema 3: Programación orientada a objetos – 52
4.4 Diseño de las subclases

 class E l i p s e : public F i g u r a {
      f l o a t ejeMenor , ejeMayor ;
 public :
      Elipse ( float a , float b) ;
      void d i b u j a r ( ) const ;
      f l o a t area ( ) const ;
      f l o a t p e r i m e t r o ( ) const ;
 };


 f l o a t E l i p s e : : area ( ) const {
      r e t u r n p i ∗ ejeMenor ∗ ejeMayor ;
 }


 void E l i p s e : : d i b u j a r ( ) const {
      // ...
 }




Programación Avanzada - Tema 3: Programación orientada a objetos – 53
4.4 Diseño de las subclases (II)

 class Rectangulo : public F i g u r a {
      f l o a t base , a l t u r a ;
 public :
      Rectangulo ( f l o a t a , f l o a t b ) ;
      void d i b u j a r ( ) const ;
      f l o a t area ( ) const ;
      f l o a t p e r i m e t r o ( ) const ;
 };


 f l o a t Rectangulo : : area ( ) const {
      r e t u r n base ∗ a l t u r a ;
 }


 void Rectangulo : : d i b u j a r ( ) const {
      // ...
 }




Programación Avanzada - Tema 3: Programación orientada a objetos – 54
4.5 Estructura de datos heterogénea

 i n t main ( ) {
                                                                                                   1
     F i g u r a ∗ v [N ] ;                                                          0
     v [ 0 ] = new Rectangulo ( . . . ) ;
     v [ 1 ] = new E l i p s e ( . . . ) ;                                                     2
     v [ 2 ] = new C i r c u l o ( . . . ) ;
     v [ 3 ] = new Cuadrado ( . . . ) ;
                                                                                           3
     // ...
     d i b u j a r ( v ) ; / / d i b u j a todas l a s f i g u r a s
     f l o a t area = a r e a T o t a l ( v ) ; / / suma de l a s áreas
                                                                                         unRectángulo   0
 }
                                                                          v[0]             atributos

                                                                          v[1]            unaElipse     1
 Definimos una estructura de datos heterogénea                                             atributos
                                                                          v[2]
 (un simple vector de punteros) que nos permita                           v[3]             unCírculo    2

                                                                                           atributos
 almacenar objetos de tipos diferentes. Recuerda                          …      …
                                                                                         unCuadrado     3

 que los punteros a objetos de una clase base                                             atributos
 pueden apuntar a objetos de cualquier clase
 derivada.
Programación Avanzada - Tema 3: Programación orientada a objetos – 55
4.6 Operaciones globales

 void d i b u j a r ( F i g u r a ∗ v [ ] ) {
                                                                                                 1
     f o r ( i n t i = 0 ; i N ; i ++)                                            0
        v [ i ]− d i b u j a r ( ) ;
 }                                                                                           2



 f l o a t areaTotal ( Figura ∗ v [ ] ) {                                                3

     f l o a t a t =0;
     f o r ( i n t i = 0 ; i N ; i ++)
        a t = a t + v [ i ]−area ( ) ;                                                unRectángulo   0

     return at ;                                                        v[0]             atributos
 }                                                                      v[1]            unaElipse     1

                                                                                        atributos
                                                                        v[2]
 Se pretende que estas dos operaciones                                  v[3]             unCírculo    2

                                                                                         atributos
 globales operen sobre el conjunto de figuras                            …      …
                                                                                       unCuadrado     3

 almacenadas en la estructura de datos. ¿Lo                                             atributos
 conseguimos realmente? Observemos la llamada
 v[i]-area()...
Programación Avanzada - Tema 3: Programación orientada a objetos – 56
4.7 Ligadura estática

  ® Ligadura estática: Se produce cuando la invocación a un método de un objeto es
        evaluada según el tipo T asociado explícitamente con su nombre en la
        declaración del mismo. La llamada v[1]-area() invoca la función
        Figura::area() porque v[1] está declarado como puntero a Figura.
        f l o a t areaTotal ( Figura ∗ v [ ] ) {
            f l o a t a t =0;
            f o r ( i n t i = 0 ; i N ; i ++)
               a t = a t + v [ i ]−area ( ) ;
            return at ;
        }


                                                                                     unaElipse
                                                                unaElipse               atributos/métodos
                                      v[1]
                                                                atributos                   de Figura
                                                                                        atributos/métodos
                                                                                             de Elipse
                                             Figura *                   Figura

                                        v[1]-area( )              Figura::area( )

Programación Avanzada - Tema 3: Programación orientada a objetos – 57
4.8 Funciones virtuales

  ® La palabra reservada virtual permite retrasar la decisión de qué método debe
        invocarse hasta el momento de la ejecución.
        class F i g u r a {
             Punto p o s i c i o n ;
             C o l o r fondo , borde ;
             // ...
        public :
             F i g u r a ( Punto p , C o l o r c1 , C o l o r c2 ) ;
             void mover ( Punto           p) ;
             v i r t u a l void d i b u j a r ( ) const ;
             v i r t u a l f l o a t area ( ) const ;
             v i r t u a l f l o a t p e r i m e t r o ( ) const ;
             // ...
        };




Programación Avanzada - Tema 3: Programación orientada a objetos – 58
4.9 Ligadura dinámica

  ® Ligadura dinámica: Se produce cuando la invocación a un método de un objeto
        es evaluada según el tipo T asociado al objeto en tiempo de ejecución. En C++
        se utiliza al invocar funciones virtuales a través de punteros o referencias. La
        llamada v[1]-area() invoca la función Elipse::area() porque v[1]
        apunta en tiempo de ejecución a una Elipse.
        f l o a t a r e a T o t a l ( F i g u r a ∗ v [ ] ) { / / s i n cambios r e s p e c t o a l a v e r s i ó n a n t e r i o r
            f l o a t a t =0;
            f o r ( i n t i = 0 ; i N ; i ++)
               a t = a t + v [ i ]−area ( ) ;
            return at ;
        }


                                                                                     unaElipse
                                                                unaElipse               atributos/métodos
                                      v[1]
                                                                atributos                   de Figura
                                                                                        atributos/métodos
                                             Figura *                   Figura               de Elipse

                                        v[1]-area( )              Elipse::area( )
Programación Avanzada - Tema 3: Programación orientada a objetos – 59
4.9 Ligadura dinámica (II)

  ® Añadimos la subclase PoligonoLibre a la jerarquía:




Programación Avanzada - Tema 3: Programación orientada a objetos – 60
4.9 Ligadura dinámica (III)

  ® La función areaTotal()
        sigue siendo válida para la
        nueva figura:
        i n t main ( ) {
            F i g u r a ∗ v [N ] ;
            // ...                                                                                          unPoligonoLibre
            v [ 3 ] = new Cuadrado ( . . . ) ;                                          unPoligonoLibre        atributos/métodos
                                                                   v[4]
            v [ 4 ] = new P o l i g o n o L i b r e ( . . . ) ;                            atributos               de Figura

            // ...                                                                                              atributos/métodos
                                                                          Figura *             Figura                de Elipse
            f l o a t area= a r e a T o t a l ( v ) ;
                                                                        v[4]-area( )        PoligonoLibre::area( )

        f l o a t areaTotal ( Figura ∗ v [ ] ) {
            f l o a t a t =0;
            f o r ( i n t i = 0 ; i N ; i ++)
               a t = a t + v [ i ]−area ( ) ;
            return at ;
        }


Programación Avanzada - Tema 3: Programación orientada a objetos – 61
4.10 Clases abstractas

  ® La clase Figura constituye una interfaz común a toda la jerarquía y contiene
        métodos cuya implementación sólo tiene sentido en las clases derivadas: las
        funciones virtuales puras.

  ® Una clase base con funciones virtuales puras se convierte en clase abstracta. Tal
        clase no puede tener instancias.
        class F i g u r a {
             // ...
        public :
             F i g u r a ( Punto p , C o l o r c1 , C o l o r c2 ) ;
             void mover ( Punto           p) ;
             v i r t u a l void d i b u j a r ( ) const = 0 ;
             v i r t u a l f l o a t area ( ) const = 0 ;
             v i r t u a l f l o a t p e r i m e t r o ( ) const = 0 ;
             // ...
        };



Programación Avanzada - Tema 3: Programación orientada a objetos – 62
4.11 Conclusiones del caso práctico

  ® La herencia puede usarse para especificar una interfaz común para un grupo de
        clases derivadas.

  ® La clase base, al especificar el prototipo de las funciones, define las operaciones
        y características requeridas por las clases derivadas y son implementadas por
        estas últimas.

  ® Esta técnica permite el diseño de programas que operan sobre objetos diferentes
        de una manera genérica: nos encontramos ante un tipo de polimorfismo.

  ® En C++ este comportamiento polimórfico se obtiene usando herencia y funciones
        virtuales.

  ® Este mecanismo es esencial a la POO y constituye la diferencia fundamental con
        respecto a la programación basada en objetos.


Programación Avanzada - Tema 3: Programación orientada a objetos – 63
Fin
   Copyright c 2004 José Luis Llopis Borrás

Realizada con ujislides c 2002-3 Sergio Barrachina (barrachi@icc.uji.es)

Weitere ähnliche Inhalte

Andere mochten auch

AdministracióN De Proceso De ImplantacióN Del Sistema
AdministracióN De Proceso De ImplantacióN Del SistemaAdministracióN De Proceso De ImplantacióN Del Sistema
AdministracióN De Proceso De ImplantacióN Del SistemaAldo Hernán Zanabria Gálvez
 
Presentacion curso ingenieria web ing. aldo zanabria
Presentacion curso ingenieria web   ing. aldo zanabriaPresentacion curso ingenieria web   ing. aldo zanabria
Presentacion curso ingenieria web ing. aldo zanabriaAldo Hernán Zanabria Gálvez
 
Jerarquía de clases, herencia, polimorfismo
Jerarquía de clases, herencia, polimorfismoJerarquía de clases, herencia, polimorfismo
Jerarquía de clases, herencia, polimorfismoEdwin Loayza
 
Fase de implementación de sistemas de información
Fase de implementación de sistemas de informaciónFase de implementación de sistemas de información
Fase de implementación de sistemas de informaciónNAHAMA19
 

Andere mochten auch (19)

Transp objetos
Transp objetosTransp objetos
Transp objetos
 
Poss0502 slides
Poss0502 slidesPoss0502 slides
Poss0502 slides
 
Poo 01
Poo 01Poo 01
Poo 01
 
Poo 03
Poo 03Poo 03
Poo 03
 
Poo transpa
Poo transpaPoo transpa
Poo transpa
 
Web 3.0 educacion aldo zanabria
Web 3.0 educacion aldo zanabriaWeb 3.0 educacion aldo zanabria
Web 3.0 educacion aldo zanabria
 
Desarrollo De Sistemas De Informaci N
Desarrollo De  Sistemas De  Informaci NDesarrollo De  Sistemas De  Informaci N
Desarrollo De Sistemas De Informaci N
 
obstruccion intestinal
obstruccion intestinalobstruccion intestinal
obstruccion intestinal
 
marketing digital
marketing digitalmarketing digital
marketing digital
 
AdministracióN De Proceso De ImplantacióN Del Sistema
AdministracióN De Proceso De ImplantacióN Del SistemaAdministracióN De Proceso De ImplantacióN Del Sistema
AdministracióN De Proceso De ImplantacióN Del Sistema
 
Memoria dinamica
Memoria dinamicaMemoria dinamica
Memoria dinamica
 
Sistemas de información distribuidos
Sistemas de información distribuidosSistemas de información distribuidos
Sistemas de información distribuidos
 
Analisis e Ingenieria de Procesos
Analisis e Ingenieria de ProcesosAnalisis e Ingenieria de Procesos
Analisis e Ingenieria de Procesos
 
Presentacion curso ingenieria web ing. aldo zanabria
Presentacion curso ingenieria web   ing. aldo zanabriaPresentacion curso ingenieria web   ing. aldo zanabria
Presentacion curso ingenieria web ing. aldo zanabria
 
Jerarquía de clases, herencia, polimorfismo
Jerarquía de clases, herencia, polimorfismoJerarquía de clases, herencia, polimorfismo
Jerarquía de clases, herencia, polimorfismo
 
Satisfaccion de las necesidades de nutrición
Satisfaccion de las necesidades de nutriciónSatisfaccion de las necesidades de nutrición
Satisfaccion de las necesidades de nutrición
 
Curriculum Vitae 2007 Aldoz
Curriculum Vitae 2007 AldozCurriculum Vitae 2007 Aldoz
Curriculum Vitae 2007 Aldoz
 
Fase de implementación de sistemas de información
Fase de implementación de sistemas de informaciónFase de implementación de sistemas de información
Fase de implementación de sistemas de información
 
Desarrollo De Sistemas De InformacióN
Desarrollo De  Sistemas De  InformacióNDesarrollo De  Sistemas De  InformacióN
Desarrollo De Sistemas De InformacióN
 

Ähnlich wie Programación orientada a objetos - Herencia en C

Metodología de la programación orientada a objetos con c++ prev
Metodología de la programación orientada a objetos con c++ prevMetodología de la programación orientada a objetos con c++ prev
Metodología de la programación orientada a objetos con c++ prevjtk1
 
Anon metodologia de la programacion orientada a objetos con c++
Anon   metodologia de la programacion orientada a objetos con c++Anon   metodologia de la programacion orientada a objetos con c++
Anon metodologia de la programacion orientada a objetos con c++ratasquerosaXX
 
Metodologia orientada a objeto - libro
Metodologia orientada a objeto -  libroMetodologia orientada a objeto -  libro
Metodologia orientada a objeto - librotaninof
 
CURSO DE PROGRAMACION BASICA - Cap 7
CURSO DE PROGRAMACION BASICA - Cap 7CURSO DE PROGRAMACION BASICA - Cap 7
CURSO DE PROGRAMACION BASICA - Cap 7Daniel Irene
 
Java
JavaJava
JavaUTN
 
programacion orientada a objetos
programacion orientada a objetosprogramacion orientada a objetos
programacion orientada a objetosjent46
 
Conceptos básicos de programación orientada a objetos (poo)
Conceptos básicos de programación orientada a objetos (poo)Conceptos básicos de programación orientada a objetos (poo)
Conceptos básicos de programación orientada a objetos (poo)Maria Garcia
 
Desarrollo de Aplicaciones Web II - Sesión 05 - Evolución de los lenguajes PO...
Desarrollo de Aplicaciones Web II - Sesión 05 - Evolución de los lenguajes PO...Desarrollo de Aplicaciones Web II - Sesión 05 - Evolución de los lenguajes PO...
Desarrollo de Aplicaciones Web II - Sesión 05 - Evolución de los lenguajes PO...Didier Granados
 
Jyoc java-cap08 principios poo
Jyoc java-cap08 principios pooJyoc java-cap08 principios poo
Jyoc java-cap08 principios pooJyoc X
 
Unidad v adsi -p2- (iii-2012)-web
Unidad v   adsi -p2- (iii-2012)-webUnidad v   adsi -p2- (iii-2012)-web
Unidad v adsi -p2- (iii-2012)-webJesús Chaparro
 

Ähnlich wie Programación orientada a objetos - Herencia en C (20)

Herencia
HerenciaHerencia
Herencia
 
Metodología de la programación orientada a objetos con c++ prev
Metodología de la programación orientada a objetos con c++ prevMetodología de la programación orientada a objetos con c++ prev
Metodología de la programación orientada a objetos con c++ prev
 
Anon metodologia de la programacion orientada a objetos con c++
Anon   metodologia de la programacion orientada a objetos con c++Anon   metodologia de la programacion orientada a objetos con c++
Anon metodologia de la programacion orientada a objetos con c++
 
Tema4 herencia
Tema4 herenciaTema4 herencia
Tema4 herencia
 
Metodologia orientada a objeto - libro
Metodologia orientada a objeto -  libroMetodologia orientada a objeto -  libro
Metodologia orientada a objeto - libro
 
Poo ok
Poo okPoo ok
Poo ok
 
CURSO DE PROGRAMACION BASICA - Cap 7
CURSO DE PROGRAMACION BASICA - Cap 7CURSO DE PROGRAMACION BASICA - Cap 7
CURSO DE PROGRAMACION BASICA - Cap 7
 
Java
JavaJava
Java
 
(9915)herencia
(9915)herencia(9915)herencia
(9915)herencia
 
programacion orientada a objetos
programacion orientada a objetosprogramacion orientada a objetos
programacion orientada a objetos
 
Conceptos básicos de programación orientada a objetos (poo)
Conceptos básicos de programación orientada a objetos (poo)Conceptos básicos de programación orientada a objetos (poo)
Conceptos básicos de programación orientada a objetos (poo)
 
Tema7 herencia
Tema7 herenciaTema7 herencia
Tema7 herencia
 
Desarrollo de Aplicaciones Web II - Sesión 05 - Evolución de los lenguajes PO...
Desarrollo de Aplicaciones Web II - Sesión 05 - Evolución de los lenguajes PO...Desarrollo de Aplicaciones Web II - Sesión 05 - Evolución de los lenguajes PO...
Desarrollo de Aplicaciones Web II - Sesión 05 - Evolución de los lenguajes PO...
 
Decorator
DecoratorDecorator
Decorator
 
Jyoc java-cap08 principios poo
Jyoc java-cap08 principios pooJyoc java-cap08 principios poo
Jyoc java-cap08 principios poo
 
06 patrones
06 patrones06 patrones
06 patrones
 
Herencia
HerenciaHerencia
Herencia
 
Unidad II_1.pptx
Unidad II_1.pptxUnidad II_1.pptx
Unidad II_1.pptx
 
Programación orientada a objetos
Programación orientada a objetosProgramación orientada a objetos
Programación orientada a objetos
 
Unidad v adsi -p2- (iii-2012)-web
Unidad v   adsi -p2- (iii-2012)-webUnidad v   adsi -p2- (iii-2012)-web
Unidad v adsi -p2- (iii-2012)-web
 

Mehr von Aldo Hernán Zanabria Gálvez

“PERSPECTIVAS DEL DESARROLLO ECONÓMICO REGIONAL EN EL CONTEXTO DEL CAMBIO CLI...
“PERSPECTIVAS DEL DESARROLLO ECONÓMICO REGIONAL EN EL CONTEXTO DEL CAMBIO CLI...“PERSPECTIVAS DEL DESARROLLO ECONÓMICO REGIONAL EN EL CONTEXTO DEL CAMBIO CLI...
“PERSPECTIVAS DEL DESARROLLO ECONÓMICO REGIONAL EN EL CONTEXTO DEL CAMBIO CLI...Aldo Hernán Zanabria Gálvez
 
Organizadores visuales sobre las corrientes contemporaneas aldo zanabria ga...
Organizadores visuales sobre las corrientes contemporaneas   aldo zanabria ga...Organizadores visuales sobre las corrientes contemporaneas   aldo zanabria ga...
Organizadores visuales sobre las corrientes contemporaneas aldo zanabria ga...Aldo Hernán Zanabria Gálvez
 
Resumen final - Seminario Taller TIC Emprede Turismo
Resumen final - Seminario Taller TIC Emprede TurismoResumen final - Seminario Taller TIC Emprede Turismo
Resumen final - Seminario Taller TIC Emprede TurismoAldo Hernán Zanabria Gálvez
 
Clase de Tecnologías de la Información y Comunicaciones
Clase de Tecnologías de la Información y ComunicacionesClase de Tecnologías de la Información y Comunicaciones
Clase de Tecnologías de la Información y ComunicacionesAldo Hernán Zanabria Gálvez
 

Mehr von Aldo Hernán Zanabria Gálvez (20)

“PERSPECTIVAS DEL DESARROLLO ECONÓMICO REGIONAL EN EL CONTEXTO DEL CAMBIO CLI...
“PERSPECTIVAS DEL DESARROLLO ECONÓMICO REGIONAL EN EL CONTEXTO DEL CAMBIO CLI...“PERSPECTIVAS DEL DESARROLLO ECONÓMICO REGIONAL EN EL CONTEXTO DEL CAMBIO CLI...
“PERSPECTIVAS DEL DESARROLLO ECONÓMICO REGIONAL EN EL CONTEXTO DEL CAMBIO CLI...
 
mejorando la web guia de html 5
mejorando la web guia de html 5mejorando la web guia de html 5
mejorando la web guia de html 5
 
Guía de Prácticas word beta.pdf
Guía de Prácticas word beta.pdfGuía de Prácticas word beta.pdf
Guía de Prácticas word beta.pdf
 
emprendimiento en la era del conocimiento.pptx
emprendimiento en la era del conocimiento.pptxemprendimiento en la era del conocimiento.pptx
emprendimiento en la era del conocimiento.pptx
 
Fundamentos de Programación
Fundamentos de ProgramaciónFundamentos de Programación
Fundamentos de Programación
 
Organizadores visuales sobre las corrientes contemporaneas aldo zanabria ga...
Organizadores visuales sobre las corrientes contemporaneas   aldo zanabria ga...Organizadores visuales sobre las corrientes contemporaneas   aldo zanabria ga...
Organizadores visuales sobre las corrientes contemporaneas aldo zanabria ga...
 
didactica
didacticadidactica
didactica
 
Tarea1 aldo zanabria
Tarea1 aldo zanabriaTarea1 aldo zanabria
Tarea1 aldo zanabria
 
Tarea 2 aldo zanabria
Tarea 2 aldo zanabriaTarea 2 aldo zanabria
Tarea 2 aldo zanabria
 
Carolinos del milenio pasado - Puno
Carolinos del milenio pasado - PunoCarolinos del milenio pasado - Puno
Carolinos del milenio pasado - Puno
 
ingenieria de sistemas
ingenieria de sistemasingenieria de sistemas
ingenieria de sistemas
 
Electricidad con recursos renovables
Electricidad con recursos renovablesElectricidad con recursos renovables
Electricidad con recursos renovables
 
Variables
VariablesVariables
Variables
 
Estructura y modelo organizacional estatal
Estructura y modelo organizacional estatal Estructura y modelo organizacional estatal
Estructura y modelo organizacional estatal
 
Calidad de Agua
Calidad de AguaCalidad de Agua
Calidad de Agua
 
Resumen final - Seminario Taller TIC Emprede Turismo
Resumen final - Seminario Taller TIC Emprede TurismoResumen final - Seminario Taller TIC Emprede Turismo
Resumen final - Seminario Taller TIC Emprede Turismo
 
Clase de Tecnologías de la Información y Comunicaciones
Clase de Tecnologías de la Información y ComunicacionesClase de Tecnologías de la Información y Comunicaciones
Clase de Tecnologías de la Información y Comunicaciones
 
Plan de Trabajo Integración de la Mujer
Plan de Trabajo Integración de la MujerPlan de Trabajo Integración de la Mujer
Plan de Trabajo Integración de la Mujer
 
peritaciones y tasación puno
peritaciones y tasación punoperitaciones y tasación puno
peritaciones y tasación puno
 
producción en la empresa turística
producción en la empresa turísticaproducción en la empresa turística
producción en la empresa turística
 

Programación orientada a objetos - Herencia en C

  • 1. Programación Avanzada - Tema 3: Programación orientada a objetos http://www3.uji.es/~llopis/II17 José Luis Llopis Borrás 15 de noviembre de 2004
  • 2. Índice 1. Introducción 4 1.1. La herencia en el mundo real . . . . . . . . . . . . . . . . . . . . . . . 5 1.2. La herencia y la teoría de conjuntos . . . . . . . . . . . . . . . . . . . . 6 1.3. El principio de los subtipos . . . . . . . . . . . . . . . . . . . . . . . . . 7 2. La herencia en la POO 8 2.1. Jerarquía de clases . . . . . . . . . . . . . . . . . . . . . . . . . . . . 10 3. Herencia pública en C++ 12 3.1. Clases derivadas . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 14 3.2. Utilización de clases base y derivadas . . . . . . . . . . . . . . . . . . . 18 3.3. El principio de los subtipos en C++ . . . . . . . . . . . . . . . . . . . . 20 3.4. Acceso a los miembros de la clase base . . . . . . . . . . . . . . . . . . 21 3.5. Miembros protegidos en la clase base . . . . . . . . . . . . . . . . . . . 22 3.6. Redefinición de miembros de la clase base . . . . . . . . . . . . . . . . 25 3.7. Herencia y constructores . . . . . . . . . . . . . . . . . . . . . . . . . . 31
  • 3. 3.8. Ligadura estática vs. dinámica . . . . . . . . . . . . . . . . . . . . . . . 42 3.9. Funciones virtuales . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 44 3.9.1. Invocación de funciones virtuales a través de un puntero . . . . . 45 3.9.2. Invocación de funciones virtuales a través de una referencia . . . 47 4. Caso práctico: aplicación gráfica 49 4.1. Identificación de objetos . . . . . . . . . . . . . . . . . . . . . . . . . . 50 4.2. Diseño de la jerarquía de clases . . . . . . . . . . . . . . . . . . . . . . 51 4.3. Diseño de la clase base . . . . . . . . . . . . . . . . . . . . . . . . . . 52 4.4. Diseño de las subclases . . . . . . . . . . . . . . . . . . . . . . . . . . 53 4.5. Estructura de datos heterogénea . . . . . . . . . . . . . . . . . . . . . 55 4.6. Operaciones globales . . . . . . . . . . . . . . . . . . . . . . . . . . . 56 4.7. Ligadura estática . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 57 4.8. Funciones virtuales . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 58 4.9. Ligadura dinámica . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 59 4.10.Clases abstractas . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 62 4.11.Conclusiones del caso práctico . . . . . . . . . . . . . . . . . . . . . . 63
  • 4. 1 Introducción ® Los seres humanos realizamos abstracciones de acuerdo con dos tipos de relaciones: parte-de y tipo-de. µ Decimos que un león tiene cuatro patas, cola larga, dientes y uñas fuertes, etc. µ Pero, seguramente, como mejor definimos un león es diciendo que es-un tipo de mamífero carnívoro, concretamente un gran felino. ® En el ámbito de los lenguajes de programación hasta ahora sólo disponíamos de una herramienta para expresar el primer tipo de relaciones: µ La composición: permite expresar relaciones parte-de (o tiene-un). Los registros de C no son más que eso, una herramienta de composición. ® La programación orientada a objetos introduce una nueva herramienta para expresar el segundo tipo de relaciones: µ La herencia: permite expresar las relaciones tipo-de (o es-un). Programación Avanzada - Tema 3: Programación orientada a objetos – 4
  • 5. 1.1 La herencia en el mundo real ® En el ejemplo siguiente, establecemos una organización jerárquica de distintos tipos de animales: µ Un león es un mamífero. µ Un león es un subtipo del tipo mamífero. µ El tipo mamífero es un supertipo de los tipos Gato y León. Animal Tipo Categoría Mamífero Ave Subtipo Subcategoría Gato León Águila Paloma Programación Avanzada - Tema 3: Programación orientada a objetos – 5
  • 6. 1.2 La herencia y la teoría de conjuntos ® El conjunto de elementos que pertenecen a un tipo incluye a los elementos que pertenezcan a sus subtipos. Animal Mamífero Ave Conjuntos anidados Gato León Águila Paloma Relación entre tipos y subtipos Edificio Motocicleta Conjuntos disjuntos No hay relación de subtipado entre estos tipos Programación Avanzada - Tema 3: Programación orientada a objetos – 6
  • 7. 1.3 El principio de los subtipos ® Principio de subtipos: “Un objeto de un subtipo puede aparecer en cualquier lugar donde se espera que aparezca un objeto del supertipo”. µ Los animales son capaces de moverse por sí mismos. µ Los mamíferos son capaces de moverse por sí mismos. µ Las aves son capaces de moverse por sí mismas. µ Los gatos son capaces de moverse por sí mismos. ® A la inversa no es cierto. µ Los gatos maullan. µ ¿Los mamíferos maullan? µ ¿Los animales maullan? Programación Avanzada - Tema 3: Programación orientada a objetos – 7
  • 8. 2 La herencia en la POO ® La herencia es un recurso fundamental en los lenguajes orientados a objetos. ® Esencialmente consiste en definir una nueva clase: µ como extensión de otra previamente definida, y µ sin modificar la ya existente. ® La nueva clase hereda de la clase base: µ los atributos (variables miembro de la clase), y µ los métodos (funciones miembro de la clase). ® Principal beneficio: la reutilización del código. µ Ahorro de esfuerzo. µ Mayor confianza en el código. Programación Avanzada - Tema 3: Programación orientada a objetos – 8
  • 9. 2 La herencia en la POO (II) ® La clase derivada es-un tipo especial de clase base. µ Un Mecánico es-un (tipo especial de) Empleado. µ Un Comercial es-un (tipo especial de) Empleado. Clase base Empleado superclase Empleado Mecánico Comercial Clase derivada Mecánico Comercial subclase Programación Avanzada - Tema 3: Programación orientada a objetos – 9
  • 10. 2.1 Jerarquía de clases ® La herencia permite establecer jerarquías de clases relacionadas entre sí. Empleado sueldoFijo ® En el ejemplo, las subclases asignarSueldo(s) heredan los datos y las sueldoBase() operaciones de la clase base. Mecanico Comercial numPiezas ventas ® Los objetos de una clase precioPorPieza derivada pueden acceder a asignarNumPrecio(n, p) asignarVentas(v) sueldo() sueldo() los miembros públicos heredados de la clase base (Versión 1) de igual forma que acceden a los propios. Programación Avanzada - Tema 3: Programación orientada a objetos – 10
  • 11. 2.1 Jerarquía de clases (II) ® Un objeto m de la clase Mecanico es además un Empleado, por tanto contiene todos los miembros de la clase base (ya sean datos o funciones) y además los propios miembros definidos en la clase derivada. Objeto m propia heredada Interfaz Interfaz asignarSueldo(s) sueldoFijo Dato sueldoBase() heredado numPiezas asignarNumPrecio(n, p) Datos precioPorPieza propios sueldo() Programación Avanzada - Tema 3: Programación orientada a objetos – 11
  • 12. 3 Herencia pública en C++ ® Vamos a realizar la implementación completa de la jerarquía formada por las clases Empleado, Mecanico y Comercial. Comenzamos con la clase base. empleado.h (versión 1) # i f n d e f EMPLEADO_H # define EMPLEADO_H class Empleado { private : float sueldoFijo ; public : void a s i gn ar S ue ld o ( f l o a t ) ; float sueldoBase ( ) const ; }; #endif Programación Avanzada - Tema 3: Programación orientada a objetos – 12
  • 13. 3 Herencia pública en C++ (II) ® La implementación de la clase base no presenta ninguna particularidad: empleado.cpp (versión 1) # include "empleado.h" void Empleado : : as ig na r Su el d o ( f l o a t s ) { sueldoFijo = s ; } f l o a t Empleado : : sueldoBase ( ) const { return sue ldoFi jo ; } Programación Avanzada - Tema 3: Programación orientada a objetos – 13
  • 14. 3.1 Clases derivadas ® Un mecánico es-un tipo especial de empleado, por lo tanto, definimos la mecanico.h (versión 1) clase Mecanico como una subclase # i f n d e f MECANICO_H # define MECANICO_H de Empleado. ® En C++ expresamos esta relación # include "empleado.h" utilizando herencia pública. También class Mecanico : public Empleado { es posible utilizar otros tipos de private : int numPiezas ; herencia, pero sólo la herencia f l o a t precioPorPieza ; pública expresa la relación es-un. public : void asignarNumPrecio ( i n t , f l o a t ) ; ® Con la herencia pública cada f l o a t sueldo ( ) const ; miembro de la clase base es }; heredado en la subclase #endif manteniendo sus privilegios de acceso. Programación Avanzada - Tema 3: Programación orientada a objetos – 14
  • 15. 3.1 Clases derivadas (II) ® En la implementación de la subclase Mecanico podemos utilizar cualquier miembro público de la clase base (p.e. sueldoBase()). ® Cuando el compilador encuentra la llamada a la función sueldoBase() primero busca la función en la clase Mecanico y, como no existe, la busca en la clase base. mecanico.cpp (versión 1) # include "mecanico.h" void Mecanico : : asignarNumPrecio ( i n t n , f l o a t p ) { numPiezas = n ; precioPorPieza = p ; } f l o a t Mecanico : : sueldo ( ) const { f l o a t complementos = numPiezas ∗ p r e c i o P o r P i e z a ; r e t u r n sueldoBase ( ) + complementos ; } Programación Avanzada - Tema 3: Programación orientada a objetos – 15
  • 16. 3.1 Clases derivadas (III) ® Un comercial es-un tipo especial de empleado, por lo tanto, definimos la clase Comercial como una subclase de Empleado. comercial.h (versión 1) # i f n d e f COMERCIAL_H # define COMERCIAL_H # include "empleado.h" class Comercial : public Empleado { private : f l o a t ventas ; public : void a si gn ar V en ta s ( f l o a t ) ; f l o a t sueldo ( ) const ; }; # e n d i f COMERCIAL Programación Avanzada - Tema 3: Programación orientada a objetos – 16
  • 17. 3.1 Clases derivadas (IV) ® Por último, implementamos la clase Comercial. ® De nuevo, desde una función miembro de la clase Comercial, podemos llamar a una función de la clase base: un Comercial no deja de ser al mismo tiempo un Empleado. comercial.cpp (versión 1) # include "comercial.h" void Comercial : : as ig n ar Ve nt a s ( f l o a t v ) { ventas = v ; } f l o a t Comercial : : sueldo ( ) const { f l o a t complementos = ventas ∗ 0 . 1 0 ; r e t u r n sueldoBase ( ) + complementos ; } Programación Avanzada - Tema 3: Programación orientada a objetos – 17
  • 18. 3.2 Utilización de clases base y derivadas test.cpp (versión 1) # include < iostream > # include "empleado.h" # include "mecanico.h" # include "comercial.h" using namespace s t d ; void f ( Empleado e ) { c o u t < < "Desde f() e.sueldoBase() = " < < e . sueldoBase ( ) < < e n d l ; } i n t main ( ) { Empleado e ; e . as ig na r Su el d o ( 1 0 0 0 ) ; c o u t < < "Sueldo del empleado: " < < e . sueldoBase ( ) < < e n d l ; Mecanico m; m. a s i gn a r S ue l do ( 2 0 0 0 ) ; m. asignarNumPrecio ( 1 0 0 , 3 ) ; c o u t < < "Sueldo del mecánico: " < < m. sueldo ( ) < < e n d l ; Programación Avanzada - Tema 3: Programación orientada a objetos – 18
  • 19. 3.2 Utilización de clases base y derivadas Comercial c ; c . as ig na r Su el do ( 3 0 0 0 ) ; c . as ig na r Ve nt as ( 2 0 0 0 ) ; c o u t < < "Sueldo del comercial: " < < c . sueldo ( ) < < e n d l ; f (e) ; f (m) ; f (c) ; } salida (versión 1) Sueldo d e l empleado : 1000 Sueldo d e l mecánico : 2300 Sueldo d e l c o m e r c i a l : 3 2 0 0 Desde f ( ) e . sueldoBase ( ) = 1 0 0 0 Desde f ( ) e . sueldoBase ( ) = 2 0 0 0 Desde f ( ) e . sueldoBase ( ) = 3 0 0 0 Programación Avanzada - Tema 3: Programación orientada a objetos – 19
  • 20. 3.3 El principio de los subtipos en C++ ® El principio de los subtipos puede enunciarse de nuevo para C++ de la manera siguiente: Una clase derivada puede aparecer en cualquier lugar donde se espera una clase base pública. ® Efectivamente: la función f() de test.cpp está definida para recibir objetos de la clase Empleado. Sin embargo, también podemos llamarla con objetos de las clases Mecánico y Comercial. ® En todo caso, desde dentro de la función f() sólo podemos acceder a los miembros públicos de la clase base. La siguiente implementación de la función f() es incorrecta puesto que sueldo() no es una función de la clase Empleado: void f ( Empleado e ) { / / i n c o r r e c t o c o u t < < "Desde f() e.sueldo() = " < < e . sueldo ( ) < < e n d l ; } Programación Avanzada - Tema 3: Programación orientada a objetos – 20
  • 21. 3.4 Acceso a los miembros de la clase base ® Hemos dicho que la clase derivada hereda todos los miembros de la clase base, pero ¿qué ocurre con los niveles de acceso? µ private Los miembros privados de la clase base no son accesibles en la clase derivada (ni en el exterior). µ public Los miembros públicos de la clase base son accesibles desde la clase derivada (y desde el exterior). ® Disponemos, además, de un nivel intermedio: µ protected Los miembros protegidos en la clase base: ª son accesibles en la clase derivada. ª no son accesibles desde el exterior. Recuerda que estamos hablando en el ámbito de la herencia pública. Programación Avanzada - Tema 3: Programación orientada a objetos – 21
  • 22. 3.5 Miembros protegidos en la clase base ® La función sueldo() de las clases Mecanico y Comercial invoca a la función sueldoBase() de la clase Empleado para averiguar cuál es el sueldo fijo del empleado. Lo hacemos así porque no podemos acceder al dato privado sueldoFijo de la clase base. ® Pero, ¿y si sueldoFijo en lugar de privado fuera protegido? En ese caso: µ sería accesible desde la función sueldo() de las subclases, µ y, al mismo tiempo, se mantendría inaccesible desde el exterior. Programación Avanzada - Tema 3: Programación orientada a objetos – 22
  • 23. 3.5 Miembros protegidos en la clase base (II) ® Declaramos el miembro sueldoFijo como protected: empleado.h (versión 1 bis) # i f n d e f EMPLEADO_H # define EMPLEADO_H class Empleado { protected : float sueldoFijo ; public : void a si gn ar S ue ld o ( f l o a t ) ; float sueldoBase ( ) const ; }; #endif Programación Avanzada - Tema 3: Programación orientada a objetos – 23
  • 24. 3.5 Miembros protegidos en la clase base (III) ® Ahora, sueldoFijo es accesible desde las clases derivadas: mecanico.cpp (versión 1 bis) ... f l o a t Mecanico : : sueldo ( ) const { f l o a t complementos = numPiezas ∗ p r e c i o P o r P i e z a ; r e t u r n s u e l d o F i j o + complementos ; } ® ... aunque sigue siendo inaccesible desde el exterior: test.cpp (versión 1 bis) i n t main ( ) { ... Mecanico m; ... c o u t m. s u e l d o F i j o ; / / i n c o r r e c t o } Programación Avanzada - Tema 3: Programación orientada a objetos – 24
  • 25. 3.6 Redefinición de miembros de la clase base ® La función sueldoBase() de la clase Empleado y las funciones sueldo() de las Empleado sueldoFijo subclases tienen el mismo asignarSueldo(s) objetivo: devolver el sueldo sueldoBase() sueldo() de una persona. No hay ninguna razón para que tengan nombres diferentes. Mecanico Comercial numPiezas ventas ® Si usamos el mismo precioPorPieza asignarNumPrecio(n, p) asignarVentas(v) nombre, conseguiremos sueldo() sueldo() uniformizar la interfaz de las (Versión 2) tres clases, facilitando su uso. Programación Avanzada - Tema 3: Programación orientada a objetos – 25
  • 26. 3.6 Redefinición de miembros de la clase base (II) ® Partiendo de la versión 1 (en la que no hay miembros protegidos), cambiamos el nombre de la función sueldoBase() por sueldo() en la clase base: empleado.h (versión 2) class Empleado { private : float sueldoFijo ; public : void a si gn ar S ue ld o ( f l o a t ) ; float sueldo ( ) const ; }; empleado.cpp (versión 2) ... f l o a t Empleado : : sueldo ( ) const { return sue ldoFij o ; } Programación Avanzada - Tema 3: Programación orientada a objetos – 26
  • 27. 3.6 Redefinición de miembros de la clase base (III) ® Al implementar las subclases, redefinimos la función sueldo() con un código diferente al que tenía en la clase base. Estamos ante una forma de sobrecarga de funciones. ® Ahora la función sueldo() de las subclases debe llamar a la función sueldo() de la clase base, pero como tiene el mismo nombre, hay que utilizar el operador de resolución de ámbito: Empleado::sueldo(). mecanico.cpp (versión 2) ... f l o a t Mecanico : : sueldo ( ) const { f l o a t complementos = numPiezas ∗ p r e c i o P o r P i e z a ; r e t u r n Empleado : : sueldo ( ) + complementos ; } µ El mismo cambio lo realizamos también en la clase Comercial. Programación Avanzada - Tema 3: Programación orientada a objetos – 27
  • 28. 3.6 Redefinición de miembros de la clase base (IV) test.cpp (versión 2) # include iostream # include empleado.h # include mecanico.h # include comercial.h using namespace s t d ; void f ( Empleado e ) { c o u t Desde f() e.sueldo() = e . sueldo ( ) e n d l ; } i n t main ( ) { Empleado e ; e . as ig na r Su el d o ( 1 0 0 0 ) ; c o u t Sueldo del empleado: e . sueldo ( ) e n d l ; Mecanico m; m. a s i gn a r S ue l do ( 2 0 0 0 ) ; m. asignarNumPrecio ( 1 0 0 , 3 ) ; c o u t Sueldo del mecánico: m. sueldo ( ) e n d l ; Programación Avanzada - Tema 3: Programación orientada a objetos – 28
  • 29. 3.6 Redefinición de miembros de la clase base (IV) Comercial c ; c . as ig na r Su el d o ( 3 0 0 0 ) ; c . as ig na r Ve nt a s ( 2 0 0 0 ) ; c o u t Sueldo del comercial: c . sueldo ( ) e n d l ; f (e) ; f (m) ; f (c) ; } salida (versión 2) Sueldo d e l empleado : 1000 Sueldo d e l mecánico : 2300 Sueldo d e l c o m e r c i a l : 3 2 0 0 Desde f ( ) e . sueldo ( ) = 1 0 0 0 Desde f ( ) e . sueldo ( ) = 2 0 0 0 Desde f ( ) e . sueldo ( ) = 3 0 0 0 Programación Avanzada - Tema 3: Programación orientada a objetos – 29
  • 30. 3.6 Redefinición de miembros de la clase base (V) ® En el archivo test.cpp podemos apreciar la uniformidad de la interfaz de las clases: calculamos el sueldo de la misma forma para objetos de los tipos Empleado, Mecanico y Comercial. ® Observa que cuando un objeto de una clase derivada invoca a la función sueldo(), el compilador elige la versión local, es decir, la de la clase derivada y no la de la clase base. µ Decimos que la función Mecanico::sueldo() oculta la función Empleado::sueldo(). i n t main ( ) { Mecanico m; ... m. sueldo ( ) ; / / siempre se e j e c u t a l a f u n c i ó n de l a c l a s e Mecanico / / y nunca l a de l a c l a s e Empleado } Programación Avanzada - Tema 3: Programación orientada a objetos – 30
  • 31. 3.7 Herencia y constructores ® Las clases que intervienen en una relación de herencia pueden contener constructores y destructores. ® Al declarar un objeto de una clase derivada, se ejecuta de forma automática: µ Primero: el constructor de la clase base. µ Segundo: el constructor de la clase derivada. ® Cuando un objeto de una clase derivada deja de existir (si es estático, porque el ámbito donde fue declarado ha acabado, y si es dinámico, porque se evalúa el operador delete) se ejecuta de forma automática: µ Primero: el destructor de la clase derivada. µ Segundo: el destructor de la clase base. ® Si el constructor de la clase base necesita argumentos para poder ejecutarse éstos deben ser facilitados por el constructor de la clase derivada a través de una lista de inicialización. Programación Avanzada - Tema 3: Programación orientada a objetos – 31
  • 32. 3.7 Herencia y constructores (II) ® Partiendo de la versión 2, añadimos constructores a nuestras clases. ® Aprovechamos la ocasión para Empleado nombre incorporar a la clase base el nombre sueldoFijo Empleado(n, s) del empleado y el operador de salida. sueldo() operator(canal, emp) ® Para simplificar el código, eliminamos las funciones Mecanico Comercial Empleado::asignarSueldo(), numPiezas ventas precioPorPieza Mecanico::asignarNumPrecio() Mecanico(n, s, num, pre) Comercial(n, s, v) sueldo() sueldo() y Comercial::asignarVentas(). (Versión 3) Programación Avanzada - Tema 3: Programación orientada a objetos – 32
  • 33. 3.7 Herencia y constructores (III) empleado.h (versión 3) # i f n d e f EMPLEADO_H # define EMPLEADO_H # include iostream # include s t r i n g using namespace s t d ; class Empleado { private : s t r i n g nombre ; float sueldoFijo ; public : Empleado ( s t r i n g , f l o a t ) ; f l o a t sueldo ( ) const ; f r i e n d ostream operator ( ostream , Empleado ) ; }; #endif Programación Avanzada - Tema 3: Programación orientada a objetos – 33
  • 34. 3.7 Herencia y constructores (IV) empleado.cpp (versión 3) # include empleado.h # include iostream # include s t r i n g using namespace s t d ; Empleado : : Empleado ( s t r i n g n , f l o a t s ) : nombre ( n ) , s u e l d o F i j o ( s ) { } f l o a t Empleado : : sueldo ( ) const { return sue ldoFi jo ; } ostream operator ( ostream canal , Empleado e ) { c a n a l e . nombre ; return canal ; } Programación Avanzada - Tema 3: Programación orientada a objetos – 34
  • 35. 3.7 Herencia y constructores (V) mecanico.h (versión 3) # i f n d e f MECANICO_H # define MECANICO_H # include empleado.h # include s t r i n g using namespace s t d ; class Mecanico : public Empleado { private : int numPiezas ; f l o a t precioPorPieza ; public : Mecanico ( s t r i n g , f l o a t , i n t , f l o a t ) ; f l o a t sueldo ( ) const ; / / o c u l t a Empleado : : sueldo ( ) }; #endif Programación Avanzada - Tema 3: Programación orientada a objetos – 35
  • 36. 3.7 Herencia y constructores (VI) mecanico.cpp (versión 3) # include empleado.h # include mecanico.h # include s t r i n g using namespace s t d ; Mecanico : : Mecanico ( s t r i n g n , f l o a t s , i n t piezas , f l o a t p r e c i o ) : Empleado ( n , s ) , numPiezas ( p i e z a s ) , p r e c i o P o r P i e z a ( p r e c i o ) { } f l o a t Mecanico : : sueldo ( ) const { f l o a t complementos = numPiezas ∗ p r e c i o P o r P i e z a ; r e t u r n Empleado : : sueldo ( ) + complementos ; } Programación Avanzada - Tema 3: Programación orientada a objetos – 36
  • 37. 3.7 Herencia y constructores (VII) comercial.h (versión 3) # i f n d e f COMERCIAL_H # define COMERCIAL_H # include empleado.h # include s t r i n g using namespace s t d ; class Comercial : public Empleado { private : f l o a t ventas ; public : Comercial ( s t r i n g , f l o a t , f l o a t ) ; f l o a t sueldo ( ) const ; / / o c u l t a Empleado : : sueldo ( ) }; #endif Programación Avanzada - Tema 3: Programación orientada a objetos – 37
  • 38. 3.7 Herencia y constructores (VIII) comercial.cpp (versión 3) # include comercial.h # include empleado.h # include s t r i n g using namespace s t d ; Comercial : : Comercial ( s t r i n g n , f l o a t s , f l o a t v ) : Empleado ( n , s ) , ventas ( v ) { } f l o a t Comercial : : sueldo ( ) const { f l o a t complementos = ventas ∗ 0 . 1 0 ; r e t u r n Empleado : : sueldo ( ) + complementos ; } Programación Avanzada - Tema 3: Programación orientada a objetos – 38
  • 39. 3.7 Herencia y constructores (IX) test.cpp (versión 3) # include empleado.h # include mecanico.h # include comercial.h # include iostream using namespace s t d ; void f ( Empleado e ) { c o u t Desde f(): ; c o u t Sueldo de e : e . sueldo ( ) e n d l ; } i n t main ( ) { Empleado e ( Maria , 1 0 0 0 ) ; c o u t Sueldo de e : e . sueldo ( ) e n d l ; Mecanico m( Ramon , 2 0 0 0 , 1 0 0 , 3 ) ; c o u t Sueldo de m : m. sueldo ( ) e n d l ; Programación Avanzada - Tema 3: Programación orientada a objetos – 39
  • 40. 3.7 Herencia y constructores (IX) Comercial c ( Luisa , 3 0 0 0 , 2 0 0 0 ) ; c o u t Sueldo de c : c . sueldo ( ) e n d l ; f (e) ; f (m) ; f (c) ; } salida (versión 3) Sueldo de Maria : 1000 Sueldo de Ramon : 2300 Sueldo de L u i s a : 3200 Desde f ( ) : Sueldo de Maria : 1000 Desde f ( ) : Sueldo de Ramon : 2000 Desde f ( ) : Sueldo de L u i s a : 3000 Programación Avanzada - Tema 3: Programación orientada a objetos – 40
  • 41. 3.7 Herencia y constructores (X) Observa que: ® Los constructores de las clases derivadas utilizan la lista de inicialización para pasar los argumentos que necesita el constructor de la clase base. Recuerda que primero se ejecuta automáticamente el constructor de la clase base y luego el de la derivada. Programación Avanzada - Tema 3: Programación orientada a objetos – 41
  • 42. 3.8 Ligadura estática vs. dinámica ® Hemos pasado por alto un detalle importante: ¿por qué la salida de la ejecución del programa test.cpp muestra dos sueldos diferentes para Ramón y para Luisa? µ Cuando se calcula el sueldo de Ramón en la función main() con m.sueldo(), la función que se ejecuta es la de la clase Mecanico, puesto que m está declarado como un objeto de esa clase. µ Cuando se calcula el sueldo de Ramón en la función f() con e.sueldo() la función que se ejecuta es la de la clase Empleado, puesto que e está declarado como un objeto de esa clase, a pesar de que en ejecución el parámetro e recibe un objeto de la clase Mecanico. ® El problema radica en cómo decide el compilador qué función debe ejecutarse, es decir, cómo se liga la llamada de una función a su ejecución. Programación Avanzada - Tema 3: Programación orientada a objetos – 42
  • 43. 3.8 Ligadura estática vs. dinámica (II) ® Existen dos tipos de ligadura: µ Ligadura estática: se produce cuando la llamada a una función de un objeto es evaluada según el tipo asociado explícitamente en la declaración del mismo. ª Esta es la ligadura que se utiliza por omisión en C y C++ y es la causa del comportamiento detectado en el programa test.cpp. µ Ligadura dinámica: se produce cuando la llamada a una función de un objeto es evaluada según el tipo asociado al objeto en tiempo de ejecución. Se conoce también como polimorfismo en tiempo de ejecución. ª En C++ este tipo de ligadura es empleada al llamar a cierto tipo de funciones especiales, conocidas como funciones virtuales, solamente cuando la llamada se hace a través de punteros o referencias. En la siguiente sección estudiaremos un caso práctico en el que la ligadura dinámica juega un papel fundamental. Programación Avanzada - Tema 3: Programación orientada a objetos – 43
  • 44. 3.9 Funciones virtuales ® Deseamos que en nuestra jerarquía de clases Empleado, Mecanico y Comercial la función sueldo() sea Empleado invocada desde la función f() nombre sueldoFijo utilizando ligadura dinámica. Para Empleado(n, s) virtual sueldo() ello debemos: operator(canal, emp) 1. Declarar como virtual la función Mecanico Comercial sueldo() en la clase base (sólo es numPiezas ventas precioPorPieza necesario hacerlo en la clase Mecanico(n, s, num, pre) Comercial(n, s, v) sueldo() sueldo() base). 2. Modificar la implementación de f() (Versión 4) para que la llamada a la función sueldo() se realice a través de un puntero o una referencia. Programación Avanzada - Tema 3: Programación orientada a objetos – 44
  • 45. 3.9.1 Invocación de funciones virtuales a través de un puntero empleado.h (versión 4) class Empleado { ... v i r t u a l f l o a t sueldo ( ) const ; }; test.cpp (versión 4) void f ( Empleado ∗ p t r _ e ) { c o u t Desde f(): ; c o u t Sueldo de ( ∗ p t r _ e ) : p t r _ e −sueldo ( ) e n d l ; } i n t main ( ) { ... f (e ) ; f (m) ; f ( c ) ; } Programación Avanzada - Tema 3: Programación orientada a objetos – 45
  • 46. 3.9.1 Invocación de funciones virtuales a través de un puntero (II) salida (versión 4) Sueldo de Maria : 1000 Sueldo de Ramon : 2300 Sueldo de L u i s a : 3200 Desde f ( ) : Sueldo de Maria : 1000 Desde f ( ) : Sueldo de Ramon : 2300 Desde f ( ) : Sueldo de L u i s a : 3200 ® La función f() recibe como argumento un puntero a un objeto de la clase Empleado y a través de él llama a la función sueldo(). ® Ante esta situación, el compilador retrasa la decisión de qué función sueldo() ejecutar hasta el momento de la ejecución. ® En cada una de las tres llamadas a la función f() se recibe como argumento un puntero a un objeto de tipo Empleado, Mecanico y Comercial respectivamente. En cada caso, ptr_e-sueldo() invoca la función sueldo() de la clase correspondiente. Programación Avanzada - Tema 3: Programación orientada a objetos – 46
  • 47. 3.9.2 Invocación de funciones virtuales a través de una referencia empleado.h (versión 5) class Empleado { ... v i r t u a l f l o a t sueldo ( ) const ; }; test.cpp (versión 5) void f ( Empleado e ) { c o u t Desde f(): ; c o u t Sueldo de e : e . sueldo ( ) e n d l ; } i n t main ( ) { ... f (e) ; f (m) ; f (c) ; } Programación Avanzada - Tema 3: Programación orientada a objetos – 47
  • 48. 3.9.2 Invocación de funciones virtuales a través de una referencia (II) salida (versión 5) Sueldo de Maria : 1000 Sueldo de Ramon : 2300 Sueldo de L u i s a : 3200 Desde f ( ) : Sueldo de Maria : 1000 Desde f ( ) : Sueldo de Ramon : 2300 Desde f ( ) : Sueldo de L u i s a : 3200 ® La función f() recibe como argumento una referencia a un objeto de la clase Empleado y a través de ella llama a la función sueldo(). ® Ante esta situación, el compilador retrasa la decisión de qué función sueldo() ejecutar hasta el momento de la ejecución. ® En cada una de las tres llamadas a la función f() se recibe como argumento un objeto de tipo Empleado, Mecanico y Comercial respectivamente. En cada caso, e.sueldo() invoca la función sueldo() de la clase correspondiente. Programación Avanzada - Tema 3: Programación orientada a objetos – 48
  • 49. 4 Caso práctico: aplicación gráfica Como ejemplo de aplicación de la ligadura dinámica (o polimorfismo en tiempo de ejecución) estudiaremos un caso práctico: una aplicación gráfica. ® Diseño de la jerarquía de clases. ® Ligadura estática. ® Ligadura dinámica y polimorfismo. ® Clases abstractas. Programación Avanzada - Tema 3: Programación orientada a objetos – 49
  • 50. 4.1 Identificación de objetos ® La aplicación gráfica debe manipular una serie de figuras como cuadrados, rectángulos, círculos, elipses, etc. Todos estos objetos se caracterizan por ciertos rasgos comunes: µ Atributos (datos) ª Coordenadas ª Color del fondo ª Color del borde ª Grosor del trazo µ Operaciones (funciones) ª Mover ª Dibujar ª Área ª Perímetro Programación Avanzada - Tema 3: Programación orientada a objetos – 50
  • 51. 4.2 Diseño de la jerarquía de clases Figura x, y, fondo, borde mover, dibujar, área, perímetro Elipse Rectángulo Triángulo ejeMayor, ejeMenor base, altura vértices dibujar, dibujar, dibujar, área, perímetro área, perímetro área, perímetro Círculo Cuadrado Notación Booch radio A B área, perímetro área, perímetro Clase A hereda de clase B Programación Avanzada - Tema 3: Programación orientada a objetos – 51
  • 52. 4.3 Diseño de la clase base class F i g u r a { Punto p o s i c i o n ; C o l o r fondo , borde ; // ... Notación Booch public : A B F i g u r a ( Punto p , C o l o r c1 , C o l o r c2 ) ; Clase A contiene void mover ( Punto p) ; una instancia de clase B void d i b u j a r ( ) const ; f l o a t area ( ) const ; 1 1 Punto f l o a t p e r i m e t r o ( ) const ; // ... Figura 1 }; 2 void F i g u r a : : mover ( Punto p ) { Color posicion = p ; } Programación Avanzada - Tema 3: Programación orientada a objetos – 52
  • 53. 4.4 Diseño de las subclases class E l i p s e : public F i g u r a { f l o a t ejeMenor , ejeMayor ; public : Elipse ( float a , float b) ; void d i b u j a r ( ) const ; f l o a t area ( ) const ; f l o a t p e r i m e t r o ( ) const ; }; f l o a t E l i p s e : : area ( ) const { r e t u r n p i ∗ ejeMenor ∗ ejeMayor ; } void E l i p s e : : d i b u j a r ( ) const { // ... } Programación Avanzada - Tema 3: Programación orientada a objetos – 53
  • 54. 4.4 Diseño de las subclases (II) class Rectangulo : public F i g u r a { f l o a t base , a l t u r a ; public : Rectangulo ( f l o a t a , f l o a t b ) ; void d i b u j a r ( ) const ; f l o a t area ( ) const ; f l o a t p e r i m e t r o ( ) const ; }; f l o a t Rectangulo : : area ( ) const { r e t u r n base ∗ a l t u r a ; } void Rectangulo : : d i b u j a r ( ) const { // ... } Programación Avanzada - Tema 3: Programación orientada a objetos – 54
  • 55. 4.5 Estructura de datos heterogénea i n t main ( ) { 1 F i g u r a ∗ v [N ] ; 0 v [ 0 ] = new Rectangulo ( . . . ) ; v [ 1 ] = new E l i p s e ( . . . ) ; 2 v [ 2 ] = new C i r c u l o ( . . . ) ; v [ 3 ] = new Cuadrado ( . . . ) ; 3 // ... d i b u j a r ( v ) ; / / d i b u j a todas l a s f i g u r a s f l o a t area = a r e a T o t a l ( v ) ; / / suma de l a s áreas unRectángulo 0 } v[0] atributos v[1] unaElipse 1 Definimos una estructura de datos heterogénea atributos v[2] (un simple vector de punteros) que nos permita v[3] unCírculo 2 atributos almacenar objetos de tipos diferentes. Recuerda … … unCuadrado 3 que los punteros a objetos de una clase base atributos pueden apuntar a objetos de cualquier clase derivada. Programación Avanzada - Tema 3: Programación orientada a objetos – 55
  • 56. 4.6 Operaciones globales void d i b u j a r ( F i g u r a ∗ v [ ] ) { 1 f o r ( i n t i = 0 ; i N ; i ++) 0 v [ i ]− d i b u j a r ( ) ; } 2 f l o a t areaTotal ( Figura ∗ v [ ] ) { 3 f l o a t a t =0; f o r ( i n t i = 0 ; i N ; i ++) a t = a t + v [ i ]−area ( ) ; unRectángulo 0 return at ; v[0] atributos } v[1] unaElipse 1 atributos v[2] Se pretende que estas dos operaciones v[3] unCírculo 2 atributos globales operen sobre el conjunto de figuras … … unCuadrado 3 almacenadas en la estructura de datos. ¿Lo atributos conseguimos realmente? Observemos la llamada v[i]-area()... Programación Avanzada - Tema 3: Programación orientada a objetos – 56
  • 57. 4.7 Ligadura estática ® Ligadura estática: Se produce cuando la invocación a un método de un objeto es evaluada según el tipo T asociado explícitamente con su nombre en la declaración del mismo. La llamada v[1]-area() invoca la función Figura::area() porque v[1] está declarado como puntero a Figura. f l o a t areaTotal ( Figura ∗ v [ ] ) { f l o a t a t =0; f o r ( i n t i = 0 ; i N ; i ++) a t = a t + v [ i ]−area ( ) ; return at ; } unaElipse unaElipse atributos/métodos v[1] atributos de Figura atributos/métodos de Elipse Figura * Figura v[1]-area( ) Figura::area( ) Programación Avanzada - Tema 3: Programación orientada a objetos – 57
  • 58. 4.8 Funciones virtuales ® La palabra reservada virtual permite retrasar la decisión de qué método debe invocarse hasta el momento de la ejecución. class F i g u r a { Punto p o s i c i o n ; C o l o r fondo , borde ; // ... public : F i g u r a ( Punto p , C o l o r c1 , C o l o r c2 ) ; void mover ( Punto p) ; v i r t u a l void d i b u j a r ( ) const ; v i r t u a l f l o a t area ( ) const ; v i r t u a l f l o a t p e r i m e t r o ( ) const ; // ... }; Programación Avanzada - Tema 3: Programación orientada a objetos – 58
  • 59. 4.9 Ligadura dinámica ® Ligadura dinámica: Se produce cuando la invocación a un método de un objeto es evaluada según el tipo T asociado al objeto en tiempo de ejecución. En C++ se utiliza al invocar funciones virtuales a través de punteros o referencias. La llamada v[1]-area() invoca la función Elipse::area() porque v[1] apunta en tiempo de ejecución a una Elipse. f l o a t a r e a T o t a l ( F i g u r a ∗ v [ ] ) { / / s i n cambios r e s p e c t o a l a v e r s i ó n a n t e r i o r f l o a t a t =0; f o r ( i n t i = 0 ; i N ; i ++) a t = a t + v [ i ]−area ( ) ; return at ; } unaElipse unaElipse atributos/métodos v[1] atributos de Figura atributos/métodos Figura * Figura de Elipse v[1]-area( ) Elipse::area( ) Programación Avanzada - Tema 3: Programación orientada a objetos – 59
  • 60. 4.9 Ligadura dinámica (II) ® Añadimos la subclase PoligonoLibre a la jerarquía: Programación Avanzada - Tema 3: Programación orientada a objetos – 60
  • 61. 4.9 Ligadura dinámica (III) ® La función areaTotal() sigue siendo válida para la nueva figura: i n t main ( ) { F i g u r a ∗ v [N ] ; // ... unPoligonoLibre v [ 3 ] = new Cuadrado ( . . . ) ; unPoligonoLibre atributos/métodos v[4] v [ 4 ] = new P o l i g o n o L i b r e ( . . . ) ; atributos de Figura // ... atributos/métodos Figura * Figura de Elipse f l o a t area= a r e a T o t a l ( v ) ; v[4]-area( ) PoligonoLibre::area( ) f l o a t areaTotal ( Figura ∗ v [ ] ) { f l o a t a t =0; f o r ( i n t i = 0 ; i N ; i ++) a t = a t + v [ i ]−area ( ) ; return at ; } Programación Avanzada - Tema 3: Programación orientada a objetos – 61
  • 62. 4.10 Clases abstractas ® La clase Figura constituye una interfaz común a toda la jerarquía y contiene métodos cuya implementación sólo tiene sentido en las clases derivadas: las funciones virtuales puras. ® Una clase base con funciones virtuales puras se convierte en clase abstracta. Tal clase no puede tener instancias. class F i g u r a { // ... public : F i g u r a ( Punto p , C o l o r c1 , C o l o r c2 ) ; void mover ( Punto p) ; v i r t u a l void d i b u j a r ( ) const = 0 ; v i r t u a l f l o a t area ( ) const = 0 ; v i r t u a l f l o a t p e r i m e t r o ( ) const = 0 ; // ... }; Programación Avanzada - Tema 3: Programación orientada a objetos – 62
  • 63. 4.11 Conclusiones del caso práctico ® La herencia puede usarse para especificar una interfaz común para un grupo de clases derivadas. ® La clase base, al especificar el prototipo de las funciones, define las operaciones y características requeridas por las clases derivadas y son implementadas por estas últimas. ® Esta técnica permite el diseño de programas que operan sobre objetos diferentes de una manera genérica: nos encontramos ante un tipo de polimorfismo. ® En C++ este comportamiento polimórfico se obtiene usando herencia y funciones virtuales. ® Este mecanismo es esencial a la POO y constituye la diferencia fundamental con respecto a la programación basada en objetos. Programación Avanzada - Tema 3: Programación orientada a objetos – 63
  • 64. Fin Copyright c 2004 José Luis Llopis Borrás Realizada con ujislides c 2002-3 Sergio Barrachina (barrachi@icc.uji.es)