Transparencias
Transcripción
Transparencias
Lenguajes de programación LPSI EUI UPM • C mejorado • Desarrollado por Bjarne Stroustrup (1986) en los laboratorios Bell de AT&T • Orientado a objetos • Basado en clases • Clase: descripción de una entidad con unas características y un comportamiento definido • Permite crear clases genéricas Lenguajes de programación LPSI EUI UPM Clases: definición class nombre { [private, protected, public]: atributos; [private, protected, public]: métodos; }; * En ficheros .h Lenguajes de programación LPSI EUI UPM Clases: implementación • Separada de la definición • En ficheros .cpp tipo nom_clase::nom_método (argum) { cuerpo; } Lenguajes de programación LPSI EUI UPM Atributos • Describen características individuales de una clase • Deben ser privados y, por tanto, sólo accesibles a través de los métodos de la clase • Se declaran como variables • class FECHA { private: unsigned dia, mes, anio; public: void inicializar (void); Lenguajes de programación LPSI EUI UPM Métodos • Definen el comportamiento de una clase • Se les llama también interfaz o protocolo de la clase • Suelen ser públicos, pero puede haber métodos privados a la clase que den servicio a los métodos públicos de la misma • Se implementan como funciones • Cada método resuelve una única acción Lenguajes de programación LPSI EUI UPM class TV_COLOR { private: unsigned canal, brillo, contraste, volumen, on_off, color, mute; public: void encender_apag (void); void subir canal (void); void bajar_canal (void) select_canal (unsigned n); void subir_vol (void); void bajar_vol (void); …… void silenciar (void); }; Lenguajes de programación LPSI EUI UPM void TV_COLOR::encender_apag (void) { if (on_off) on_off = 0; else { canal = 1; volumen = 8; brillo = 5; contraste = 5; mute = 0; color = 6; on_off = 1; } } void TV_COLOR::subir_canal (void) { if (on_off) canal = ++canal % 100; } Lenguajes de programación LPSI EUI UPM void TV_COLOR::bajar_canal (void) { if (on_off) if (canal) canal --; else canal = 99; } void TV_COLOR::select_canal (unsigned n) { if (on_off) canal = n %100; } void TV_COLOR::silenciar (void) { if (on_off) mute = 1; } Lenguajes de programación LPSI EUI UPM void TV_COLOR::subir_vol (void) { if (on_off) { mute = 0; if (25 > volumen) volumen++; } } Lenguajes de programación LPSI EUI UPM Objetos • Instancias de una clase (clase <-> tipo, objeto <-> vble) • Se definen a partir de clases • Se manejan enviándoles mensajes • Mensaje: petición a un objeto para que ejecute uno de los métodos de su clase: objeto.método punt_obj->método (con punteros) * this es un puntero al objeto que ha recibido un mensaje Lenguajes de programación LPSI EUI UPM void main (void) { TV_COLOR tv_lp, *punt_tv = &tv_lp; tv_lp.encender_apag(); tv_lp.subir_canal (); punt_tv->bajar_brillo (); punt_tv->select_canal (12); tv_lp.silenciar (); punt_tv->silenciar(); } Lenguajes de programación LPSI EUI UPM Constructores • Métodos públicos de una clase que se llaman igual que ella • Se ejecutan implícitamente al declarar un objeto de la clase • Se usan para inicializar o crear un objeto • No se envían como mensaje a un objeto • No devuelven ningún valor (ni siquiera son de tipo void) Lenguajes de programación LPSI EUI UPM class COMPLEJO { private: float real, imag; public: COMPLEJO (void); void inicializar (float, float); void imprimir (void); float parte_real (void); float parte_imag (void); void asignar (COMPLEJO); }; Lenguajes de programación LPSI EUI UPM COMPLEJO::COMPLEJO (void) { real = imag = 0.0; } void COMPLEJO::inicializar (float r, float i) { real = r; imag = i; } Lenguajes de programación LPSI EUI UPM float COMPLEJO::parte_real (void) { return (real); } float COMPLEJO::parte_imag (void) { return (imag); } void COMPLEJO::imprimir (void) { cout << real << “ “ << imag; } Lenguajes de programación LPSI EUI UPM void COMPLEJO::asignar (COMPLEJO c) { real = c.parte_real (); imag = c.parte_imag (); } Lenguajes de programación LPSI EUI UPM Sobrecarga de métodos • Varios métodos públicos de una misma clase, que realizan la misma acción y por tanto tienen el mismo nombre, pero que lo hacen de forma diferente • Deben diferenciarse en los argumentos, bien en tipo, en número o en ambos • La ejecución de un método u otro se realiza a partir del mensaje recibido por el objeto Lenguajes de programación LPSI EUI UPM class COMPLEJO { private: …… public: COMPLEJO (void); COMPLEJO (float); COMPLEJO (float, float); void inicializar (float, float); void inicializar (COMPLEJO); ……………. Lenguajes de programación LPSI EUI UPM COMPLEJO::COMPLEJO (float r) { real = r; imag = 0.0; } COMPLEJO::COMPLEJO (float r, float i) { real = r; imag = i; } Lenguajes de programación LPSI EUI UPM void COMPLEJO::inicializar (COMPLEJO c) { real = c.parte_real (); imag = c.parte_imag (); } void main (void) { COMPLEJO a, b(5.8), c(2.6, 10.4); a.asignar (COMPLEJO (1.0, 1.0)); a.inicializar (c); …… } Lenguajes de programación LPSI EUI UPM Sobrecarga de operadores • Redefinición de operadores definidos en el lenguaje para que operen con objetos de la clase que se está definiendo • Pueden darse varias formas a un operador sobrecargado • El formato es: tipo operatorop (argumentos) * A partir de la sobrecarga se pueden utilizar como se usan habitualmente Lenguajes de programación LPSI EUI UPM public: COMPLEJO operator+ (COMPLEJO); void operator= (COMPLEJO); ………. COMPLEJO COMPLEJO::operator+ (COMPLEJO c) { return (COMPLEJO (real + c.parte_real, imag + c.parte_imag)); } void COMPLEJO::operator= (COMPLEJO c) { real = c.parte_real; imag = c.parte_imag; } Lenguajes de programación LPSI EUI UPM void main (void) { COMPLEJO a, b, c (1.0, 1); b = c; a = b + c; a.operator= (b.operator+ (c)); …….. Lenguajes de programación LPSI EUI UPM Destructores • Realizan tareas de finalización para un objeto: liberar memoria, cierre de ficheros,… • Una clase sólo puede tener un único destructor (no admite sobrecarga) • Tiene el mismo nombre que la clase pero precedido del carácter ~ • No devuelve ningún valor ni tiene argumentos, ni siquiera void • Se ejecuta implícitamente justo antes de que se destruya el objeto, no hay que pasarlo como mensaje al mismo Lenguajes de programación LPSI EUI UPM class NODO { private: int num; NODO * sig; public: NODO(); void poner_num (int); int ver_num (void); void poner_sig (NODO *); NODO * ver_sig (void); }; Lenguajes de programación LPSI EUI UPM class PILA_INT { private: unsigned n_elem; NODO * pila; public: PILA_INT (); void apilar (int); int cima (void); void desapilar (void); int vacia (void); unsigned num_elem (void); ~PILA_INT(); }; Lenguajes de programación LPSI EUI UPM PILA_INT::PILA_INT() { pila = NULL; n_elem = 0; } void PILA_INT::apilar (int n) { NODO *aux; new (aux); aux->poner_sig (pila); aux->poner_num (n); pila = aux; n_elem++; } Lenguajes de programación LPSI EUI UPM void PILA_INT::desapilar (void) { NODO *aux = pila; if (pila) { pila = aux->ver_sig(); n_elem--; delete (aux); } } int PILA_INT::cima (void) { return (pila->ver_num()); } Lenguajes de programación LPSI EUI UPM int PILA_INT::vacia (void) { return (!pila); } unsigned PILA_INT::num_elem (void) { return (n_elem); } Lenguajes de programación LPSI EUI UPM PILA_INT::~PILA_INT() { NODO *aux; while (pila) { aux = pila; pila = pila->ver_sig(); delete (aux); } } Lenguajes de programación LPSI EUI UPM Métodos inline • Se implementan: – en la definición de la clase – fuera de la clase, como cualquier método, pero se los califica con la palabra inline en la definición de la clase • El compilador sustituye la llamada por el código del método • Son más eficientes en cuanto a ejecución • Sólo para métodos con poco código Lenguajes de programación LPSI EUI UPM class PILA_INT { private: unsigned n_elem; NODO * pila; public: PILA_INT () { pila = NULL; n_elem = 0; }; void apilar (int); inline int cima (void); void desapilar (void); int vacia (void) { return (!pila); }; unsigned num_elem (void) { return (n_elem); }; ~PILA_INT(); }; Lenguajes de programación LPSI EUI UPM Atributos y métodos estáticos • Son únicos para todos los objetos de la clase, todos los objetos creados los comparten • Son como vbles globales que sólo pueden usarse por los objetos de una clase • Sólo se pueden acceder mediante métodos definidos como estáticos • Los métodos estáticos deben ser públicos • Puede usarse la clase como receptor de un mensaje Lenguajes de programación LPSI EUI UPM class CALABAZA { private: static unsigned total; unsigned kilos; public: CALABAZA (unsigned k) { kilos = K; total += kilos; }; …………. static unsigned total_kilos (void) { return total; } } Lenguajes de programación LPSI EUI UPM Relaciones entre clases: composición • Cuando uno o más atributos de una clase son objetos de otra u otras clases • Normalmente responde a la pregunta “¿Tiene un?” • Es una relación estable, sólo acaba cuando desaparece el objeto contenedor class FECHA { private: unsigned dia, mes, anio; public: …….. }; Lenguajes de programación LPSI EUI UPM class ALUMNO { private: char nombre[15], apell[45]; FECHA f_nac; ………. public: ……….. }; Lenguajes de programación LPSI EUI UPM Relaciones entre clases: agregación • Cuando uno o más atributos de una clase son referencias (claves, punteros,…) a objetos de otra u otras clases • Los objetos referenciados pueden existir al margen del objeto referenciador Lenguajes de programación LPSI EUI UPM class ASIGNATURA { …………. }; Class ALUMNO_ASIG { private: ASIGNATURA *matriculas[15]; char dni[10]; public: …….. }; Lenguajes de programación LPSI EUI UPM class PRESTAMO { private: char dni[10], signatura[12]; FECHA f_prest; public: ………. }; Lenguajes de programación LPSI EUI UPM Relaciones entre clases: uso • Cuando una clase usa uno o más objetos de otra u otras para realizar una o más tareas (métodos) • La relación de uso se establece a través de los métodos. Un método tiene declarados parámetros, tipo de resultado o vbles locales que son objetos o referencias a objetos de otras clases • Es una relación temporal, dura lo que dura el método Lenguajes de programación LPSI EUI UPM class HORA { private: unsigned hh, mm, ss; public: ………. }; class TICKET { private: FECHA f_in, f_out; HORA h_in, h_out; public: …… }; Lenguajes de programación LPSI EUI UPM class PARKING { private: unsigned n_plazas, libres, prec_hora; public: PARKING (unsigned n) { n_plazas = libres = n; }; void pon_precio_h (void); TICKET entra_coche (void); TICKET pagar (TICKET); void sale_coche (TICKET); unsigned plazas_libres (void); }; Lenguajes de programación LPSI EUI UPM Relaciones entre clases: herencia • Para definir una nueva clase a partir de otra. La nueva clase incorpora las características y comportamiento de otra clase existente y añade otras propias • La nueva clase debe ser una especialización (o generalización) de la existente • Directamente relacionada con la reutilización de código • Normalmente responde a la pregunta “¿es un?” • La clase heredada se llama clase base, padre o superclase • La clase que hereda se llama clase derivada, hija o subclase Lenguajes de programación LPSI EUI UPM • Los métodos de la clase base no tienen acceso a la clase derivada • Posibilidad de declarar miembros protegidos en la clase base: class X { private: …… protected: …… public: …….. }; • Los métodos de la clase derivada tienen acceso a las partes pública y protegida de su clase base Lenguajes de programación LPSI EUI UPM • La parte protegida de una clase sólo está accesible para sus derivadas directas • Un objeto de una clase derivada lo es también de su clase base, y es posible asignar un objeto de una clase base a otro de una clase derivada • Es posible redefinir métodos de una clase base en la clase derivada o anularlos • Una clase puede heredar de otra de forma: pública, protegida o privada; Lenguajes de programación LPSI EUI UPM class BASE { private: tipo1 atr1; protected: tipo2 atr2, atr3; public: m1(); m2(); }; Lenguajes de programación LPSI EUI UPM class DERIVADA: public BASE { private: tipo3 atr4; public: BASE Privado m3(); Protegido m4(); Público m5(); }; DERIVADA inaccesible protegido público Lenguajes de programación LPSI EUI UPM class DERIVADA: protected BASE { private: tipo3 atr4; public: BASE Privado m3(); Protegido m4(); Público m5(); }; DERIVADA inaccesible protegido protegido Lenguajes de programación LPSI EUI UPM class DERIVADA: private BASE { private: tipo3 atr4; public: BASE Privado m3(); Protegido m4(); Público m5(); }; DERIVADA inaccesible privado privado Lenguajes de programación LPSI EUI UPM Herencia, constructores y destructores • Cuando una clase base tiene un constructor, la clase derivada está obligada a llamar a ese constructor • Si el constructor de la clase base tiene parámetros, el de la clase derivada está obligado a pasarle los parámetros que necesite • Primero se ejecutan los constructores de la clase base y después los de las derivadas • La destrucción empieza en las clases derivadas y acaba en las bases Lenguajes de programación LPSI EUI UPM class BASE { ……. public: BASE (); BASE (int, float); ~BASE (); ……….. }; Class DERIV: public BASE { ……. public: DERIV (); DERIV (int a, int b, float c): BASE (a, c); ~DERIV (); …………. }; Lenguajes de programación LPSI EUI UPM Métodos virtuales • Son métodos de una clase base que se van a redefinir en las clases derivadas • Si se envía un mensaje a un objeto de la clase derivada con un método redefinido, se ejecutará siempre el de esta clase, a no ser que se especifique explícitamente que se quiere ejecutar el de la clase base • Métodos virtuales puros son aquéllos que no se implementan en la clase base, sólo sirven para ser redefinidos en la clase derivada Lenguajes de programación LPSI EUI UPM class BASE { …… public: virtual m1(); virtual m2 () = 0; ……….. }; class DERIV: public BASE { ……. public: m1(); m2(); …………. }; Lenguajes de programación LPSI EUI UPM void main (void) { DERIV obj; obj.m1(); // el de la derivada obj.BASE::m1(); // el de la base obj.m2(); // el de la derivada obj.BASE::m2(); // error ………. Lenguajes de programación LPSI EUI UPM Clase base abstracta • Aquélla que representa un concepto abstracto y de la que, por tanto, no van a existir objetos • Se utiliza para la definición de clases derivadas • Es abstracta toda clase con uno o más métodos virtuales puros • No se pueden declarar objetos de clases abstractas • Un método virtual puro que no se redefina en la clase derivada pasa a ésta como virtual puro, por lo que la derivada también será abstracta Lenguajes de programación LPSI EUI UPM Herencia múltiple • Una clase hereda de varias clases base • Cada una de las herencias puede ser pública, privada o protegida, independientemente del resto • Cada una de las partes de las clases base sigue los criterios de visibilidad de la herencia simple Lenguajes de programación LPSI EUI UPM class DERIV: public BASE1, private BASE2, public BASE3 { …………. }; • Cuando dos o más clases base tengan métodos iguales, hay que deshacer la ambigüedad precediendo al método con su clase: obj.CLASE::método ambiguo Lenguajes de programación LPSI EUI UPM Herencia virtual A B C D Lenguajes de programación LPSI EUI UPM class B: virtual public A { ………. }; class C: virtual public A { ………. }; class d: public B, public C { ………. }; Lenguajes de programación LPSI EUI UPM Polimorfismo dinámico • Herramienta que permite manejar objetos de distintas clases de manera uniforme. Todos los objetos polimórficos responden a los mismos mensajes, pero sólo se ejecuta el método del objeto activo • Se construye en base a: herencia, métodos virtuales y punteros • La clase base es abstracta • Los objetos polimórficos pertenecen a las clases derivadas • Todas las clases derivadas deben tener el mismo interfaz • Herramienta potente para reutilización de código Lenguajes de programación LPSI EUI UPM FIGURA CIRCULO CUADRADO RECTANGULO PENTAGONO Lenguajes de programación LPSI EUI UPM class FIGURA { private: char color; public: FIGURA (char c) { color = c; }; virtual void inicializar (void) = 0; virtual float area (void) = 0; virtual void pintar (void) = 0; }; Lenguajes de programación LPSI EUI UPM class CIRCULO: public FIGURA { private: PUNTO centro; unsigned radio; public: CIRCULO (char c): FIGURA (c) { }; void inicializar (void) float area (void); void pintar (void); }; Lenguajes de programación LPSI EUI UPM class CUADRADO: public FIGURA { private: PUNTO vsupiz, vinfdcho; public: CUADRADO (char c): FIGURA (c) { }; void inicializar (void) float area (void); void pintar (void); }; Lenguajes de programación LPSI EUI UPM class RECTANGULO: public FIGURA { private: PUNTO vsupiz, vinfdcho; public: RECTANGULO (char c): FIGURA (c) { }; void inicializar (void) float area (void); void pintar (void); }; Lenguajes de programación LPSI EUI UPM class PENTAGONO: public FIGURA { private: PUNTO vertices[5]; public: PENTAGONO (char c): FIGURA (c) { }; void inicializar (void) float area (void); void pintar (void); }; Lenguajes de programación LPSI EUI UPM class CUADRO { private: FIGURA * lienzo[25]; unsigned n_fig; public: CUADRO (); void menu (void); void aniadir_fig (void) void area (void); void pintar (void); }; Lenguajes de programación LPSI EUI UPM CUADRO::CUADRO () { int i; for (i = 0, i < 25; i++) lienzo[i] = NULL; n_fig = 0; } CUADRO::area (void) { float total = 0.0; unsigned i; for (i = 0; i < n_fig; i++) total += lienzo[i]->area(); cout << “El área total de las figuras es: “; cout << total; } Lenguajes de programación LPSI EUI UPM CUADRO::pintar (void) { unsigned i; for (i = 0; i < n_fig; i++) lienzo[i]->pintar(); } Lenguajes de programación LPSI EUI UPM void CUADRO::aniadir_fig (void) { char opcion, color; if (25 == n_fig) return; cout << “Figura a añadir: “; do { cout << “1.- Círculo. \n“; cout << “2.- Cuadrado. \n“; cout << “3.- Rectángulo. \n“; cout << “4.- Pentágono. \n“; cout << “ Elija una opción: “; cin >> opcion; } while (‘1’ > opcion || ‘4’ < opcion); cout << “\n\nIntroduzca el color (1..10): “; cin >> color; Lenguajes de programación LPSI EUI UPM switch (opcion) { case ‘1’: lienzo[n_fig] = new (CIRCULO(color); break; case ‘2’: lienzo[n_fig] = new (CUADRADO(color); break; case ‘3’: lienzo[n_fig] = new (RECTANGULO(color); break; case ‘4’: lienzo[n_fig] = new (PENTAGONO(color); }; lienzo[n_fig]->inicializar (); } Lenguajes de programación LPSI EUI UPM void CUADRO::menu (void) { char opcion; do { do { cout << “1.- Añadir figura. \n“; cout << “2.- Pintar el cuadro. \n“; cout << “3.- Calcular el área pintada. \n“; cout << “ 0.- Salir.\n\n”; cout << “Elija una opción: “; cin >> opcion; } while (‘0’ > opcion || ‘3’ < opcion); Lenguajes de programación LPSI EUI UPM switch (opcion) { case ‘1’: aniadir_fig (); break; case ‘2’: pintar (); break; case ‘3’: area (); }; } while (‘0’ != opcion); } void main (void) { CUADRO las_meninas; las_meninas.menu(); } Lenguajes de programación LPSI EUI UPM Clases parametrizadas • Clases genéricas a modo de plantillas • Herramienta más potente de reutilización de código • La clase genérica se programa una vez y se particulariza para los tipos de elementos que se requieran en cada caso • El compilador sustituye el parámetro genérico con el tipo usado en la particularización Lenguajes de programación LPSI EUI UPM template <class elem> class PILA_100 { private: elem apilados[100]; unsigned n_elem; public: PILA_100 () {n_elem = 0);}; void apilar (elem e); void desapilar (void); elem cima (void) int vacía (void) {return (! n_elem);}; unsigned num_elem (void) {return (n_elem);}; }; Lenguajes de programación LPSI EUI UPM template <class elem> void PILA_100<elem>:: apilar (elem e) { if (100 > n_elem) apilados [n_elem++] = e; } template <class elem> PILA_100<elem>:: desapilar (void) { if (0 < n_elem) n_elem--; } Lenguajes de programación LPSI EUI UPM template <class elem> elem PILA_100<elem>:: cima (void) { return (apilados [n_elem-1]); } void main (void) { PILA_100 <int> pila_enteros; PILA_100 < FECHA> pila_fechas; pila_enteros.apilar(12); ………….. } Lenguajes de programación LPSI EUI UPM