550 likes | 903 Views
Programación Orientada a Objetos. Aunque no existe un caracterización precisa acerca de qué es un lenguaje orientado a objetos en general se acuerda que debe soportar: Abstracción de datos y encapsulamiento Herencia Polimorfismo y ligadura linámica
E N D
Programación Orientada a Objetos Aunque no existe un caracterización precisa acerca de qué es un lenguaje orientado a objetos en general se acuerda que debe soportar: Abstracción de datos y encapsulamiento Herencia Polimorfismo y ligadura linámica Java brinda soporte para todos estos conceptos. Introducción a la Programación Orientada a Objetos
Abstracción de Datos y Encapsulamiento La abstracción de datos es una metodología de diseño que consiste en identificar las entidades de un problema y agruparlas de acuerdo a sus atributos y comportamiento. Los lenguajes que soportan esta metodología brindan mecanismos para definir tipos de datos abstractos. Un tipo de dato abstracto define un patrón de comportamiento para todas las instancias del tipo. La representación de los datos y la implementación de las operaciones de un tipo de dato abstracto: está encapsulada, no es visible desde el exterior es la misma para todas las instancias. En muchas aplicaciones esta visión constituye una fuerte limitación, muchas instancias puedan estar caracterizadas por algunos atributos y algunas operaciones en común, no necesariamente compartirán todos. Introducción a la Programación Orientada a Objetos
Herencia El diseño de una aplicación orientada a objetos consiste en: Identificar y caracterizar los objetos relevantes de un problema Clasificar los objetos en clases según atributos y comportamiento Clasificar las clases Las clases son las unidades fundamentales a partir de las cuales se construye el programa. La herencia permite que las clases más generales puedan especializarse en otras más específicas. Introducción a la Programación Orientada a Objetos
Polimorfismo Una variable polimórficapuedereferenciar a objetos de diferentesclases. Una variable tiene un tipoestáticoquecorresponde a la declaración y un tipodinámicoque lo determina el objetoligado en ejecución. Unaasignaciónpolimórficaasocia a una variable declarada de unaclase dada, un objeto de unaclasederivada. Un métodopolimórficorecibecomoparámetros a variables polimórficas. Introducción a la Programación Orientada a Objetos
Ligadura Dinámina El tipoestáticode una variable es la clasequeaparece en la declaración El tipodinámicode una variable es la clase del objeto al queestáligada en ejecución. Cuando un método se redefine la ligadura entre un mensaje y un métodoquedadeterminadapor la clase del objeto, estoes, por el tipodinámico de una variable. Introducción a la Programación Orientada a Objetos
Chequeo de tipos El tipoestáticode una variable determina los mensajesquepuederecibir. El compiladorchequeaque no va a habererrores en ejecución. El tipodinámicode la variable determina el métodoque se ejecuta en respuesta a un mensaje. El compilador no puedeestablecer la ligadura entre un mensaje y el método, es la clase del objeto en ejecución la que lo determina. Introducción a la Programación Orientada a Objetos
Caso de Estudio: Maquinas Expendedoras MaquinaExpendedora R101 M111 R101Plus Introducción a la Programación Orientada a Objetos
Caso de Estudio: Maquinas Expendedoras MaquinaExpendedora <<atributos de clase>> maxCafe: entero maxCacao: entero maxTe : entero <<atributos de instancia>> NroSerie : entero cantCafe: entero cantCacao: entero cantTe : entero <<constructor>> MaquinaExpendedora (ns : entero) <<comandos>> cafe() te() cargarCafe(grs: entero) : entero… <<consultas>> masCafe(MaquinaExpendedora e): MaquinaExpedendora Cadamáquinatiene un númeroque la identifica Introducción a la Programación Orientada a Objetos
Caso de Estudio: Maquinas Expendedoras M111 <<atributos de clase>> maxLeche: entero … <<atributos de instancia>> cantLeche: entero … <<constructor>> M111(ns : entero) <<comandos>> te() teConLeche subMarino()… cargarLeche(grs: entero) : entero… <<consultas>> obtenerCantLeche(): entero… obtenerMaxLeche(): entero … vasosTeConLeche() : entero Introducción a la Programación Orientada a Objetos
Caso de Estudio: Maquinas Expendedoras R101 <<atributos de clase>> maxCrema: entero … <<atributos de instancia>> cantCrema: entero … <<constructor>> R101(ns : entero) <<comandos>> te() carioca()… cargarCrema(grs: entero) : entero… <<consultas>> obtenerCantCrema(): entero… obtenerMaxCrema(): entero … vasosCarioca() : entero … Introducción a la Programación Orientada a Objetos
Caso de Estudio: Maquinas Expendedoras R101Plus <<atributos de clase>> maxCanela: entero … <<atributos de instancia>> cantCanela: entero … <<constructor>> R101Plus(ns : entero) <<comandos>> cafe() bahiano()… cargarCanela(grs: entero) : entero… <<consultas>> obtenerCantCanela(): entero… obtenerMaxCanela(): entero … vasosBahiano() : entero … El métodocafe() se redefine Introducción a la Programación Orientada a Objetos
Caso de Estudio: Maquinas Expendedoras Una variable polimórfica puede quedar asociada a objetos de diferentes clases. Una asignación polimórfica liga un objeto de una clase a una variable declarada de otra clase MaquinaExpendedora me = new M111(nro1); M111 me Introducción a la Programación Orientada a Objetos
Caso de Estudio: Maquinas Expendedoras Una variable polimórfica puede quedar asociada a objetos de diferentes clases. Una asignación polimórfica liga un objeto de una clase a una variable declarada de otra clase MaquinaExpendedora me = new M111(nro1); … me = new R101(nro2); M111 me R101 Introducción a la Programación Orientada a Objetos
Caso de Estudio: Maquinas Expendedoras MaquinaExpendedora me; R101 r = new R101(nro); me = r; • El tipo estático de me es MaquinaExpendedora • El tipo dinámico de me es R101; El tipo estático MaquinaExpendedora determina el conjunto de tipos dinámicos para me. El mismo criterio se aplica al pasaje de parámetros. Introducción a la Programación Orientada a Objetos
Caso de Estudio: Maquinas Expendedoras class MaquinaExpendedora {… … public MaquinaExpendedora masCafe (MaquinaExpendedora m) { //Asume m ligada if (cantCafe > m.obtenerCantCafe()) return this; else return m; } } MaquinaExpendedora me1,me2,m3; R101 meR101 = new R101(nro1); me1 = new R101Plus(nro2); me2 = meR101.masCafe(me1); me3 = me1.masCafe(meR101); Introducción a la Programación Orientada a Objetos
Caso de Estudio: Maquinas Expendedoras El chequeo de tipo impone algunas limitaciones al nivel de polimorfismo Una variable polimórfica sólo puede referenciar a objetos de su clase o de las clases derivadas. Una asignación polimórfica asocia un objeto de una clase a una variable cuyo tipo estático es una clase ancestro de la clase del objeto. R101 meR101 = new R101(nro1); R101Plus meR101Plus ; El compilador rechaza : meR101Plus= new R101(nro2); meR101Plus= meR101; Introducción a la Programación Orientada a Objetos
Caso de Estudio: Maquinas Expendedoras El casting relaja el control del compilador. R101 meR101 = new R101(nro); R101Plus meR101Plus ; if (meR101 instanceof R101Plus) meR101Plus= (R101Plus) meR101; Es responsabilidad del programador asegurar que el objeto referenciado por meR101 sea efectivamente de clase R101Plus Si no se incluye el condicional y meR101 no referencia a un objeto de clase R101Plus se produce una excepción en ejecución. Introducción a la Programación Orientada a Objetos
Caso de Estudio: Maquinas Expendedoras MaquinaExpendedora te() cafe() masCafe(me) R101 te() carioca() M111 te() teconLeche() submarino() R101Plus bahiano() cafe() Introducción a la Programación Orientada a Objetos
Caso de Estudio: Maquinas Expendedoras Una variable polimórfica determina los mensajes que un objeto puede recibir, aunque el objeto determina la implementación específica del comportamiento que se ejecuta en respuesta a los mensajes. R101 meR101 ; R101Plus meR101Plus = new R101Plus (nro); meR101 = meR101Plus; El compilador rechaza meR101.bahiano(); Introducción a la Programación Orientada a Objetos
Caso de Estudio: Maquinas Expendedoras class MaquinaExpendedora { … public void cafe() { cantCafe=cantCafe–40; } … } MaquinaExpendedora me; R101Plus meR101Plus; meR101Plus=new R101Plus(nro); me = meR101Plus; me.cafe(); class R101Plus extends R101 { … public void cafe() { cantCafe=cantCafe-45; } … } Introducción a la ProgramaciónOrientada a Objetos
En un hospital cada una de los pasillos tiene un número asignado a partir de 0. Cada pasillo tiene previsto un espacio para colocar una máquina expendedora, aunque no todos los pasillos tienen una. La clase MEHospital modela la tabla de máquinas expendedoras asignadas a los pasillos y brinda servicios para computar la cantidad total de café que contienen las máquinas y la cantidad total de leche entre los modelos M111. Caso de Estudio: ME en un Hospital Introducción a la Programación Orientada a Objetos
Caso de Estudio: ME en un Hospital MaquinaExpendedora MEHospital R101 M111 R101Plus MEHospital es una tabla Introducción a la Programación Orientada a Objetos
Caso de Estudio: ME en un Hospital MEHospital Asigna la máquina unaMe al pasillo p que asume válidoi MaquinaExpendedora[] T El pasillo p, que asume válido, no queda ligado a una máquinai <<constructores>> MEHospital(max : entero) <<comandos>> insertar( unaME : MaquinaExpendedora, p:entero) eliminar (p:entero) <<consultas>> maxElementos():entero cantElementos():entero hayElementos(): boolean estaLlena () boolean existeElemento(unaME : MaquinaExpendedora) : boolean totalVasosCafe () : entero totalLeche() : entero Calcula la cantidad de pasillos que tienen una máquina Decide si al menos un pasillo tiene una máquina Decide si todos los pasillos tienen una máquina Computa la cantidad total de vasos de café entre todas las máquinas Computa la cantidad total de leche entre todas las máquinas M111 Introducción a la Programación Orientada a Objetos
Caso de Estudio: ME en un Hospital public void insertar (MaquinaExpendedora me, int p) { /*Inserta me en la posicion p, que asume valida*/ T[p] = me; } public void eliminar(int p){ /*Elimina la máquina de la posicion p, que asume valida*/ T[p] = null; } El arreglo está constituido por un conjunto de variables polimórficas. Introducción a la ProgramaciónOrientada a Objetos
Caso de Estudio: ME en un Hospital public int maxElementos(){ /*Cantidad de pasillos*/ return T.length; } public int cantElementos(){ /*Calcula la cantidad de pasillos que tienen asignada una máquina expendedora*/ int cant = 0; for (int i=0; i< maxElementos();i++) if (T[i] != null) cant++; return cant; } Introducción a la ProgramaciónOrientada a Objetos
Caso de Estudio: ME en un Hospital public boolean estaLlena(){ /*Decide si todos los pasillos tienen asignada una máquina*/ int i = 0; boolean hay=false; while (i < maxElementos() && !hay){ if (T[i] == null) hay = true ; i++; } return !hay; } Introducción a la ProgramaciónOrientada a Objetos
Caso de Estudio: ME en un Hospital class Test { MEHospital lote; … MaquinaExpendedora m1,m2,m3,m4; m1 = new M111(11); m2 = new R101Plus(12); m3 = new R101 (13); … lote.insertar(m1,1); lote.insertar(m2,2); lote.insertar(m3,4); … } Como es una tabla no necesitamos controlar que la tabla no esté llena. Todos los elementos tienen el mismo tipo estático, la estructura es homogénea. Introducción a la ProgramaciónOrientada a Objetos
Caso de Estudio: ME en un Hospital class MEHospital{ private MaquinaExpendedora[] T; NroSerie cantCafé cantTe cantCacao cantLeche T NroSerie cantCafé cantTe cantCacao cantCrema cantCanela NroSerie cantCafé cantTe cantCacao cantCrema Todas tiene el ingrediente café Introducción a la ProgramaciónOrientada a Objetos Introducción a la Programación Orientada a Objetos
Caso de Estudio: ME en un Hospital public int totalVasosCafe (){ int c = 0; for (int i = 0; i <maxElementos();i++) { if (T[i] != null) c = c+T[i].vasosCafe(); } return c; } La operación vasosCafe() está provista para todas las máquinas. Introducción a la ProgramaciónOrientada a Objetos
Caso de Estudio: ME en un Hospital MaquinaExpendedora café() vasosCafe() MEHospital R101 M111 R101Plus café() vasosCafe() Introducción a la ProgramaciónOrientada a Objetos
Caso de Estudio: ME en un Hospital class MEHospital{ private MaquinaExpendedora[] T; NroSerie cantCafé cantTe cantCacao cantLeche T NroSerie cantCafé cantTe cantCacao cantCrema cantCanela NroSerie cantCafé cantTe cantCacao cantCrema Solo algunas tienen leche Introducción a la ProgramaciónOrientada a Objetos Introducción a la Programación Orientada a Objetos
Caso de Estudio: ME en un Hospital public int totalLeche (){ int c = 0; M111 aux; for (int i = 0; i <maxElementos();i++) { if (T[i] != null && T[i] instanceof M111){ aux =(M111)T[i]; c=c+aux.obtenerCantLeche();} } return c; } La operación obtenerCantLeche() sólo está provista para los objetos de clase M111. Introducción a la ProgramaciónOrientada a Objetos
Caso de Estudio: ME en un Hospital public boolean existeElemento (MaquinaExpendedora unElem){ /* Decide si hay un elemento con la misma identidad que unElem, que asume ligada*/ int i = 0; boolean esta=false; while (i < maxElementos() && !esta){ if (T[i] != null) esta = T[i] == unElem; i++; } return esta; } Introducción a la ProgramaciónOrientada a Objetos
Caso de Estudio: ME en un Hospital public boolean existeElemento (MaquinaExpendedora unElem){ /* Decide si hay un elemento equivalente a unElem, que asume ligada*/ int i = 0; boolean esta=false; while (i < cantME && !esta){ if (T[i] != null) esta = T[i].equals(unaMe); i++; } return esta; } El mensaje equals debe ligarse con el método que corresponda a la clase del objeto asociado T[i]. Consideremos este caso un poco más adelante. Introducción a la ProgramaciónOrientada a Objetos
Caso de Estudio: ME en un Hospital MaquinaExpendedora <<atributos de clase>> maxCafe: entero maxCacao: entero maxTe : entero <<atributos de instancia>> NroSerie : entero cantCafe: entero cantCacao: entero cantTe : entero <<constructor>> MaquinaExpendedora (ns : entero) <<comandos>> cafe() te() cargarCafe(grs: entero) : entero… <<consultas>> igualNroSerie(me:MaquinaExpendedora) : boolean Introducción a la Programación Orientada a Objetos
Caso de Estudio: ME en un Hospital class MaquinaExpendedora { public boolean igualNroSerie(MaquinaExpendedora m){ return NroSerie == m.obtenerNroSerie(); } } Todas las máquinas expendedoras tienen un número de serie que las identifica. Este número sirve de clave de búsqueda, para identificar a cada instancia particular. Este servicio no compara todos los atributos, sólo el número de serie. Introducción a la Programación Orientada a Objetos
Caso de Estudio: ME en un Hospital public boolean existeElemento (MaquinaExpendedora unElem){ /* Decide si hay un elemento equivalente a unElem, que asume ligada*/ int i = 0; boolean esta=false; while (i < cantME && !esta){ if (T[i] != null) esta = T[i].igualNroSerie (unaMe); i++; } return esta; } En este caso el diseñador considera que dos máquinas son equivalentes si tienen el mismo número de serie. Introducción a la ProgramaciónOrientada a Objetos
Caso de Estudio: ME en un Hospital M111 <<atributos de clase>> maxLeche: entero … <<atributos de instancia>> cantLeche: entero … <<constructor>> M111(ns : entero) <<comandos>> te() teConLeche subMarino()… cargarLeche(grs: entero) : entero… <<consultas>> obtenerCantLeche(): entero… obtenerMaxLeche(): entero … vasosTeConLeche() : entero El métodoigualNroSeriese hereda de la clase base, en la cualestátambién el atributo clave Introducción a la Programación Orientada a Objetos
Caso de Estudio: ME en un Hospital En la fábrica toda máquina expendedora es de clase M111, R101 o R101Plus, no existen máquinas que queden modeladas con la clase MaquinaExpendedora. MaquinaExpendedora R101 M111 R101Plus Introducción a la ProgramaciónOrientada a Objetos
Caso de Estudio: ME en un Hospital En el diseño la clase MaquinaExpendedora permite factorizar los atributos y comportamiento que comparten todas las máquinas de la fábrica. La clase MaquinaExpendedora es entonces abstracta, en la aplicación no hay entidades de esa clase y en ejecución no habrá instancias de clase máquina expendedora. Toda clase abstracta tiene que especializarse en al menos una clase concreta, esto es una clase que modele a entidades del problema. Introducción a la ProgramaciónOrientada a Objetos
Caso de Estudio: ME en un Hospital Con frecuencia una clase general establece algunos de los servicios que brindan todas sus instancias, sin llegar a implementarlos de manera concreta. En el ejemplo de la fábrica de las máquinas expendedoras todas las máquinas brindan el servicio te() pero la implementación concreta varía según el tipo de máquina. Introducción a la ProgramaciónOrientada a Objetos
Caso de Estudio: ME en un Hospital *MaquinaExpendedora <<atributos de instancia>> … <<comandos>> *te() <<consultas>> *vasosTe() R101 M111 <<atributos de instancia>> … <<comandos>> te() <<consultas>> vasosTe() <<atributos de instancia>> … <<comandos>> te() <<consultas>> vasosTe() Introducción a la ProgramaciónOrientada a Objetos
Caso de Estudio: ME en un Hospital En Java, el modificador abstract permite declarar una clase abstracta. abstract class MaquinaExpendedora { } Una clase abstracta puede contener uno o más métodos abstractos, esto es, la clase especifica un servicio pero no indica cómo se implementa. public abstract void te() ; public abstract int vasosTe(); Introducción a la ProgramaciónOrientada a Objetos
Caso de Estudio: ME en un Hospital Todas las máquinas expendedoras ofrecen el servicio te() pero la implementación varía. class abstract MaquinaExpendedora { public abstract void te() ; } class M111 extends MaquinaExpendedora { public void te() { this.retirarTe (10); } class R101 extends MaquinaExpendedora{ public void te() { this.retirarTe (15); } } Introducción a la ProgramaciónOrientada a Objetos
Caso de Estudio: ME en un Hospital Todas las máquinas expendedoras ofrecen el servicio vasosTe() pero la implementación varía. class abstract MaquinaExpendedora { public abstract int vasosTe() ; } class M111 extends MaquinaExpendedora { public int vasosTe() { return this.obtenerCantTe() / 10; } class R101 extends MaquinaExpendedora{ public int vasosTe() { return this.obtenerCantTe() / 15;} } Introducción a la ProgramaciónOrientada a Objetos
Caso de Estudio: ME en un Hospital class MEHospital{… public int totalVasosTe (){ int c = 0; for (int i = 0; i <maxElementos();i++) { if (T[i] != null) c = c+T[i].vasosTe(); } return c; } } … } El arreglo está constituido por un conjunto de variables polimórficas. La operación vasosTe() está provista para todas. Introducción a la ProgramaciónOrientada a Objetos
Caso de Estudio: ME en un Hospital Una clase abstracta solo va a ser usada para definir clases más específicas, pero no va a tener instancias. De modo que la declaración que sigue es válida: MaquinaExpendedora me; Pero el compilador reportará un error si se intenta crear una instancia: me = new MaquinaExpendedora(nro); Introducción a la ProgramaciónOrientada a Objetos
Caso de Estudio: ME en un Hospital MaquinaExpendedora me; M111 meM111; me = new M111(nro1); meM111 = new M111(nro2); me.te(); meM111.te(); Ambos mensajes se ligarán al métodote() provistopor la claseM111. Introducción a la ProgramaciónOrientada a Objetos
Caso de Estudio: ME en un Hospital MaquinaExpendedora me; R101 meR101; R101Plus meR101Plus; me = new R101(nro1); meR101 = new R101(nro2); meR101Plus = new R101Plus(nro3); me.te(); meR101.te(); meR101Plus.te(); Los mensajes se ligarán al métodote() provistopor la claseR101. Introducción a la ProgramaciónOrientada a Objetos
Clases Abstractas En la jerarquía de clases que modelan un sistema, las clases de los niveles superiores son generales y las de los niveles inferiores son más específicas. Una clase es abstracta si no está asociada a entidades del problema. En ejecución no va a haber instancias de una clase abstracta. Las clases abstractas pueden identificarse en la etapa de diseño de la aplicación o pueden crearse artificialmente durante la implementación. Una clase abstracta puede tener uno o más métodos abstractos. Introducción a la ProgramaciónOrientada a Objetos