INTRODUCCIN A LA PROGRAMACIN ORIENTADA A OBJETOS Asociacin
INTRODUCCIÓN A LA PROGRAMACIÓN ORIENTADA A OBJETOS Asociación y Dependencia de Clases Sonia Rueda Depto. de Ciencias e Ingeniería de la Computación Universidad Nacional del Sur, Bahía Blanca 01100 10011 10110 01110 1001 1 11 0 0 1
RELACIONES ENTRE CLASES Un sistema orientado a objetos se construye a partir de una colección de clases relacionadas entre sí. Algunas clases cumplen el rol de proveedoras de servicios. Algunas clases cumplen el rol de clientes de los servicios 0 1 1 0 0 10011 que brindan las clases proveedoras. Algunas clases son proveedoras de servicios y a su vez clientes de otras clases proveedoras. Las funcionalidades y responsabilidades establecen un contrato entre las clases relacionados. Introducción a la Programación Orientada a Objetos IPOO - 2019 101100 10011 10110 01110 1001 1 11 0 0 1 2
RELACIONES ENTRE CLASES Asociación La asociación es una forma de relación entre clases y se produce cuando el modelo de un objeto del problema contiene o puede contener al modelo de otro objeto del 01100 problema. 10011 10110 01110 La dependencia es una forma de relación entre clases y 0 1 1 0 0 10011 se produce cuando el modelo de un objeto del problema 1 0 1 1 0 01110 usa al modelo de otro objeto. 1001 1 11 0 0 1 Dependencia Introducción a la Programación Orientada a Objetos IPOO - 2019 3
DEPENDENCIA ENTRE CLASES Cuando una clase A brinda un servicio que declara una variable local, retorna un resultado o recibe un parámetro de otra clase B, decimos que: • la clase A depende de la clase B y • la relación es de tipo usa. Un. En particular existe una relación de dependencia entre clase tester y la clase verificada. Introducción a la Programación Orientada a Objetos IPOO - 2019 01100 10011 101100 10011 una 10110 01110 1001 1 11 0 0 1 4
ASOCIACIÓN ENTRE CLASES Cuando una clase A tiene un atributo de instancia de otra clase B, decimos que – las clases están asociadas y – la relación es de tipo tiene. Un. 01100 Entre dos clases asociadas en general también se 10011 10110 establece una relación de dependencia. 01110 Algunos de los servicios de la clase cliente, recibirán como 01100 10011 parámetro o retornarán un resultado de la clase proveedora. 10110 Así, una clase A que tiene un atributo de la clase B, usa 0 a 1 1 1 0 1001 la clase B. 1 11 0 0 1 Introducción a la Programación Orientada a Objetos IPOO - 2019 5
CASO DE ESTUDIO: VIDEOJUEGO En un videojuego algunos de los personajes son aliens. Los aliens tienen cierta cantidad de antenas y de manos, que determinan su capacidad sensora y su capacidad de lucha respectivamente. Cada alien tiene una cantidad de vidas que inicialmente es 5 y 01 10 10 01 01 se van reduciendo cada vez que recibe una herida. 10110 01110 Cuando está muerto ya no tienen efecto las heridas. 01100 10011 10110 01110 1001 1 11 0 0 1 Introducción a la Programación Orientada a Objetos IPOO - 2019 6
CASO DE ESTUDIO: VIDEOJUEGO Cuando un alien logra llegar a la base recupera 2 vidas, sin superar nunca el valor 5. Cada alien tiene una nave, cada nave tiene una velocidad y una cantidad de combustible en el tanque. 01100 Ambos atributos pueden aumentar o disminuir de acuerdo a un 10011 parámetro que puede ser positivo o negativo. 10110 01110 La fuerza de un alien se calcula como la capacidad sensora, más 01100 su capacidad de lucha, todo multiplicado por el número de vidas 10011 10110 por un quinto de la velocidad de la nave. 01110 1001 1 11 0 0 1 Introducción a la Programación Orientada a Objetos IPOO - 2019 7
CASO DE ESTUDIO: VIDEOJUEGO Alien <<Atributos de clase>> max. Vidas: entero <<Atributos de instancia>> Nave: Nave. Espacial vidas: entero antenas: entero manos: entero <<Constructores>> Alien (n: Nave. Espacial, v, a, m: entero) <<Comandos>> recupera. Vidas() recibe. Herida() copy(a: Alien) establecer. Nave(n: Nave. Espacial) establecer. Antenas(p: entero) establecer. Manos(p: entero) establecer. Vidas(p: entero) Alien(n: Nave. Espacial, v, a, m: entero) Requiere n ligado y v <= 5 copy(a: Alien) Requiere a ligado 01100 10011 10110 01110 1001 1 11 0 0 1
CASO DE ESTUDIO: VIDEOJUEGO Alien <<Atributos de clase>> max. Vidas: entero <<Atributos de instancia>> Nave: Nave. Espacial vidas: entero antenas: entero manos: entero … <<Consultas>> obtener. Nave(): Nave. Espacial obtener. Vidas(): entero obtener. Antenas(): entero obtener. Manos(): entero obtener. Fuerza(): real clone(): Alien equals(a: Alien): boolean obtener. Fuerza(): real Requieren Nave ligado equals(a: Alien): boolean Requiere a ligado 01100 10011 10110 01110 1001 1 11 0 0 1
CASO DE ESTUDIO: VIDEOJUEGO Nave. Espacial <<Atributos de instancia>> velocidad: entero combustible: entero <<Constructores>> Nave. Espacial(v, c: entero) <<Comandos>> cambiar. Velocidad(v: entero) cambiar. Combustible(c: entero) copy(n: Nave. Espacial) <<Consultas>> obtener. Velocidad(): entero obtener. Combustible(): entero equals(n: Nave. Espacial): boolean clone(): Nave. Espacial Introducción a la Programación Orientada a Objetos Nave. Espacial(v, c: entero) Requiere c>=0, v>=0 cambiar. Combustible(p: entero) Si combustible+p >=0 combustible = combustible+p 0 1 1 0 0 10011 cambiar. Velocidad(p: entero) 10110 Si velocidad+p >=0 01110 velocidad = velocidad+p 01100 10011 10110 01110 1001 1 11 0 0 1 10
CASO DE ESTUDIO: VIDEOJUEGO La clase Alien es cliente de la clase proveedora Nave. Espacial. La clase Alien solo necesita conocer la signatura de los servicios provistos por Nave. Espacial. La clase Nave. Espacial no necesita conocer a la Alien ni a ninguna de sus clases clientes. Introducción a la Programación Orientada a Objetos IPOO - 2019 01100 clase 1 0 0 1 1 101100 10011 10110 01110 1001 1 11 0 0 1 11
CASO DE ESTUDIO: VIDEOJUEGO class Nave. Espacial { //Atributos de instancia private int velocidad; private int combustible; //Constructor public Nave. Espacial(int v, int c){ //Requiere v>= 0 c>= 0 velocidad = v; combustible = c; } 01100 10011 10110 01110 1001 1 11 0 0 1 12
CASO DE ESTUDIO: VIDEOJUEGO //Comandos public void cambiar. Velocidad(int p){ if (velocidad+p >=0) velocidad= velocidad+p; } public void cambiar. Combustible (int p){ if (combustible+p >=0) combustible = combustible+p; } //Consultas public int obtener. Velocidad(){ return velocidad; } public int obtener. Combustible (){ return combustible; } 01100 10011 10110 01110 1001 1 11 0 0 1 13
CASO DE ESTUDIO: VIDEOJUEGO class Nave. Espacial { //Atributos de instancia private int velocidad; private int combustible; … public void copy(Nave. Espacial n){ //Requiere n ligada. velocidad= n. obtener. Velocidad(); combustible= n. obtener. Combustible(); } El comando copy al parámetro, en el mensaje. 01100 10011 10110 01110 1001 copia el estado interno del objeto ligado 1 11 estado interno del objeto que recibe el 0 0 1
CASO DE ESTUDIO: VIDEOJUEGO class Nave. Espacial { //Atributos de instancia private int velocidad; private int combustible; … public boolean equals(Nave. Espacial n){ //Requiere n ligada return velocidad== n. obtener. Velocidad()&& combustible== n. obtener. Combustible(); } 01100 10011 10110 01110 1001 La consulta equals decide si dos objetos son 1 11 equivalentes, esto es, retorna true si el objeto que recibe el 0 0 mensaje tiene el mismo estado interno que el objeto ligado 1 al parámetro. 15
CASO DE ESTUDIO: VIDEOJUEGO class Nave. Espacial { //Atributos de instancia private int velocidad; private int combustible; 01100 public Nave. Espacial clone(){ 10011 10110 return new Nave. Espacial(velocidad, 01110 combustible); 01100 } 10011 10110 01110 La consulta clone retorna un nuevo objeto con el mismo 1 0 0 1 1 11 estado interno que el objeto que recibió el mensaje. 0 0 1 16
CASO DE ESTUDIO: VIDEOJUEGO Alien <<Atributos de clase>> max. Vidas: entero <<Atributos de instancia>> Nave: Nave. Espacial vidas: entero antenas: entero manos: entero class Alien { //Atributos de clase private static final int max. Vidas = 5; //Atributos de instancia private Nave. Espacial Nave; 0 1 1 0 0 private int vidas; 10011 private int antenas; 10110 private int manos; 01110 01100 } 10011 10110 01110 1001 Las clases Alien y Nave. Espacial están asociadas. 1 1 1 0 0 La clase Alien tiene un atributo de clase Nave. Espacial 1
CASO DE ESTUDIO: VIDEOJUEGO Alien <<Constructores>> Alien (n: Nave. Espacial, v, a, m: entero) //Constructor public Alien (Nave. Espacial n, int v, int a, int m){ // Requiere n ligado y v <=5 Nave = n; 01100 vidas = v; 10011 antenas = a; 10110 manos = m; 01110 01100 } Cuando se crea un objeto de clase Alien queda asociado a un objeto de clase Nave. Espacial. La clase cliente de Alien tiene la responsabilidad de asegurar que el parámetro real está ligado. 10011 10110 01110 1001 1 11 0 0 1
CASO DE ESTUDIO: VIDEOJUEGO Alien <<Comandos>> recupera. Vidas() recibe. Herida() establecer. Nave(n: Nave. Espacial) establecer. Antenas(p: entero) establecer. Manos(p: entero) establecer. Vidas(p: entero) //Comandos public void recupera. Vidas(){ if (vidas+2 > max. Vidas) vidas = max. Vidas; else vidas = vidas+2; } 01100 10011 public void recibe. Herida(){1 0 1 1 0 if (vida > 0) vida--; 01110 01100 } 10011 10110 01110 1001 1 11 0 0 1
CASO DE ESTUDIO: VIDEOJUEGO Alien <<Consultas>> obtener. Nave(): Nave. Espacial obtener. Vidas(): entero obtener. Antenas(): entero obtener. Manos(): entero //Consultas public Nave. Espacial obtener. Nave(){ return Nave; } public int obtener. Vidas(){ 0 1 1 0 0 return vidas; 10011 } 10110 public int obtener. Antenas(){ 01110 01100 return antenas; 10011 } public int obtener. Manos (){1 0 1 1 0 01110 return manos; 1001 } 1 11 0 0 1
CASO DE ESTUDIO: VIDEOJUEGO Alien <<Consultas>> obtener. Fuerza(): real //Consultas public float obtener. Fuerza(){ return (float) (antenas+manos)*vidas* Nave. obtener. Velocidad() / 5; 01100 } 10011 101100 La consulta obtener. Fuerza de la clase Alien envía el 10011 mensaje obtener. Velocidad a un objeto de la clase 1 0 1 1 0 01110 asociada Nave. 1001 1 11 La clase Alien asume que el atributo de instancia Nave 0 0 está ligada, ya que este es un compromiso asumido por 1 las clases que la usan.
CASO DE ESTUDIO: VIDEOJUEGO public void copy (Alien a){ //Requiere a ligada Nave = a. obtener. Nave(); vidas = a. obtener. Vidas(); antenas= a. obtener. Antenas(); manos = a. obtener. Manos(); Copy superficial } 01100 10011 10110 01110 El comando copy asigna al alien que recibe el mensaje la 1 0 0 1 1 11 misma cantidad de vidas, antenas y manos que el alien que 0 0 pasa como parámetro y lo asocia también a la misma 1 nave.
CASO DE ESTUDIO: VIDEOJUEGO public void copy (Alien a){ //Requiere a ligada Nave = a. obtener. Nave(); vidas = a. obtener. Vidas(); antenas= a. obtener. Antenas(); manos = a. obtener. Manos(); } Se modifica la identidad del atributo de instancia 01100 10011 10110 01110 1001 1 11 Nave. 0 0 1
CASO DE ESTUDIO: VIDEOJUEGO public Alien clone(){ return new Alien(Nave, vidas, manos, antenas); } 01100 10011 Clone superficial 1 0 1 1 0 01110 01100 10011 10110 01110 1001 La consulta clone crea y devuelve un alien con la misma 1 11 cantidad de vidas, antenas y manos que el alien que recibe 0 0 el mensaje y asociado también a la misma nave. 1
CASO DE ESTUDIO: VIDEOJUEGO public boolean equals (Alien a){ //Requiere a ligada return (Nave == a. obtener. Nave()&& vidas == a. obtener. Vidas()&& manos == a. obtener. Manos()&& 01100 antenas == a. obtener. Antenas()); 10011 10110 } equals superficial 01110 01100 La consulta equals retorna true si el alien que recibe el 1 0 0 1 1 10110 mensaje y el que pasa como parámetro son equivalentes. 01110 1001 Dos aliens son equivalentes si tienen la misma cantidad de vidas, manos y antenas y ambos están asociados a la 10 10 1 misma nave. Es decir los atributos de instancia Nave de los 1 dos objetos de clase Alien tienen la misma identidad.
CASO DE ESTUDIO: VIDEOJUEGO public boolean equals (Alien a){ //Requiere a ligada return (Nave == a. obtener. Nave()&& vidas == a. obtener. Vidas()&& manos == a. obtener. Manos()&& antenas == a. obtener. Antenas()); } 01100 10011 101100 El operador relacional compara la identidad de la nave del 10011 10110 alien que recibió el mensaje con la identidad de la nave del 01110 alien que recibe como parámetro. 1001 1 11 0 0 1
CASO DE ESTUDIO: VIDEOJUEGO class Video. Juego{ public static void main (String s[]){ Nave. Espacial n 1 = new Nave. Espacial (100, 45); Nave. Espacial n 2 = new Nave. Espacial (100, 65); Alien a 1, a 2, a 3, a 4; a 1 = new Alien(n 1, 3, 2, 4); a 4 = new Alien(n 2, 2, 3, 4); a 2 = a 1. clone(); a 3 = a 1; a 4. copy(a 1); System. out. println(a 1==a 2); System. out. println(a 1==a 3); System. out. println(a 1==a 4); a 1. recibe. Herida(); System. out. println(a 1==a 2); System. out. println(a 1==a 3); System. out. println(a 1==a 4); } } 01100 10011 10110 01110 1001 1 11 0 0 1
CASO DE ESTUDIO: VIDEOJUEGO class Video. Juego{ public static void main (String s[]){ Nave. Espacial n 1 = new Nave. Espacial (100, 45); Nave. Espacial n 2 = new Nave. Espacial (100, 65); Alien a 1, a 2, a 3, a 4; a 1 = new Alien(n 1, 3, 2, 4); a 4 = new Alien(n 2, 2, 3, 4); a 2 = a 1. clone(); a 3 = a 1; System. out. println(a 1. equals((a 2)); System. out. println(a 1. equals((a 3)); System. out. println(a 1. equals((a 4)); a 1. recibe. Herida(); a 4. copy(a 1); System. out. println(a 1. equals((a 2)); System. out. println(a 1. equals((a 3)); System. out. println(a 1. equals((a 4)); } } 01100 10011 10110 01110 1001 1 11 0 0 1
CASO DE ESTUDIO: VIDEOJUEGO public void copy(Alien a){ //Requiere a ligado y Nave ligado en los dos aliens } Nave. copy(a. obtener. Nave()); vidas = a. obtener. Vidas(); antenas= a. obtener. Antenas(); 01100 10011 manos = a. obtener. Manos(); Copy en profundidad 101100 Copia en el alien que recibe el mensaje la cantidad de 1 0 0 1 1 10110 vidas, antenas y manos del alien que pasa como parámetro. 01110 1001 En la nave asociada al alien que recibe el mensaje, copia el estado interno de la nave asociada al alien que pasa 1 1 1 0 0 como parámetro. 1 29
CASO DE ESTUDIO: VIDEOJUEGO public void copy(Alien a){ //Requiere a ligado y Nave ligado en los dos aliens Nave. copy(a. obtener. Nave()); vidas = a. obtener. Vidas(); antenas= a. obtener. Antenas(); manos = a. obtener. Manos(); } 01100 10011 10110 Observemos que no cambia la identidad del atributo de 01 10 10 11 0 instancia Nave sino el estado interno del objeto ligado a la 1 11 0 0 variable. 1 30
CASO DE ESTUDIO: VIDEOJUEGO public Alien clone(){ Nave. Espacial n = Nave. clone(); return new Alien (n, vidas, manos, antenas); } Clone en profundidad 01100 10011 10110 Crea un alien con la misma cantidad de vidas, manos y 0 1 1 1 0 antenas que el alien que recibe el mensaje y lo asocia a 0 1 1 0 0 10011 una nueva nave, equivalente a la nave del alien que recibe 10110 el mensaje clone. 01110 1001 1 11 0 0 1 31
CASO DE ESTUDIO: VIDEOJUEGO public boolean equals (Alien a){ /*Requiere a ligada y Nave ligada en los dos aliens*/ Equals en profundidad return (Nave. equals(a. obtener. Nave())&& 01100 10011 vidas == a. obtener. Vidas()&& 10110 manos == a. obtener. Manos()&& 01110 antenas == a. obtener. Antenas()); 01100 10011 } En este caso, se considera que dos aliens son equivalentes tienen la misma cantidad de vidas, manos antenas y están asociados a naves equivalentes. 10110 01110 1001 y 1 1 1 0 0 1 32
CASO DE ESTUDIO: VIDEOJUEGO public void copy(Alien a){ //Requiere a ligado y Nave ligado en los dos aliens } nave = a. obtener. Nave(); vidas = a. obtener. Vidas(); antenas= a. obtener. Antenas(); manos = a. obtener. Manos(); Copy superficial public void copy(Alien a){ //Requiere a ligado y Nave ligado en los dos } 01100 10011 101100 10011 aliens 10110 01110 1001 1 11 0 0 1 Nave. copy(a. obtener. Nave()); vidas = a. obtener. Vidas(); antenas= a. obtener. Antenas(); manos = a. obtener. Manos(); Copy en profundidad 33
CASO DE ESTUDIO: VIDEOJUEGO public Alien clone. S(){ return new Alien(nave, vidas, manos, antenas); } Clone superficial public Alien clone. P(){ Nave. Espacial n = nave. clone(); return new Alien(n, vidas, manos, antenas); } Clone en profundidad Introducción a la Programación Orientada a Objetos IPOO - 2019 01100 10011 10110 01110 1001 1 11 0 0 1 34
CASO DE ESTUDIO: VIDEOJUEGO public boolean equals. S (Alien a){ return Nave == a. obtener. Nave()&& vidas == a. obtener. Vidas()&& manos == a. obtener. Manos()&& antenas == a. obtener. Antenas()); 01100 } equals superficial 1 0 0 1 1 101100 10011 10110 01110 1001 1 11 0 0 1 public boolean equals. P (Alien a){ return Nave. equals(a. obtener. Nave())&& vidas == a. obtener. Vidas()&& manos == a. obtener. Manos()&& antenas == a. obtener. Antenas()); } Introducción a la Programación Orientada a Objetos equals en profundidad 35 IPOO - 2019
CASO DE ESTUDIO: VIDEOJUEGO En un videojuego algunos de los personajes son aliens. Los aliens tienen cierta cantidad de antenas y de manos, que determinan su capacidad sensora y su capacidad de lucha respectivamente. Cada alien tiene un nombre y una cantidad de vidas que inicialmente es 5 y se van reduciendo cada vez que recibe una herida. Cuando está 01100 muerto ya no tienen efecto las heridas. Cuando un alien logra llegar 1 a 0 0 1 1 10110 la base recupera 2 vidas, sin superar nunca el valor 5. 01110 Cada alien tiene una nave, cada nave tiene una velocidad y una 01100 cantidad de combustible en el tanque. Ambos atributos pueden 10011 aumentar o disminuir de acuerdo a un parámetro que puede ser 1 0 1 1 0 01110 positivo o negativo. 1001 La fuerza de un alien se calcula como la capacidad sensora, más su 1 1 1 capacidad de lucha, todo multiplicado por el número de vidas. 0 0 1 Introducción a la Programación Orientada a Objetos IPOO - 2019 36
Alien <<Atributos de clase>> max. Vidas: entero <<Atributos de instancia>> Nave: Nave. Espacial vidas: entero antenas: entero manos: entero <<Constructores>> Alien (n: Nave. Espacial, a, m: entero) <<Comandos>> recupera. Vidas() recibe. Herida() copy(a: Alien) <<Consultas>> obtener. Nave(): Nave. Espacial obtener. Vidas(): entero obtener. Antenas(): entero obtener. Manos(): entero obtener. Fuerza(): real clone(): Alien equals(a: Alien): boolean class Alien { //Atributos de clase private static final int max. Vidas = 5; //Atributos de instancia private Nave. Espacial Nave; private int vidas; private int antenas; private int manos; //Constructor public Alien (Nave. Espacial n, int a, int m){ Nave = n; vidas = max. Vidas; antenas = a; manos = m; } } El cambio afecta a la implementación de la consulta 37 clone().
- Slides: 37