Download Unidad I Conceptos Fundamentales de Programación Orientada a

Document related concepts
no text concepts found
Transcript
Unidad I Conceptos Fundamentales de Programación Orientada a Objetos 1.1.
El paradigma orientado a objetos.
La programación orientada a objetos es una de las formas más populares de programar y viene teniendo gran acogida en el desarrollo de proyectos de software desde los últimos años. Esta acogida se debe a sus grandes capacidades y ventajas frente a las antiguas formas de programar. Por la creciente tendencia de crear programas cada vez más grandes y complejos los desarrolladores crearon una nueva forma de programar con la capacidad de crear sistemas de niveles empresariales y con reglas de negocios muy complejas. Para estas necesidades ya no bastaba la programación estructurada ni mucho menos la programación lineal. Es así como aparece la programación orientada a objetos (POO). La POO viene de la evolución de la programación estructurada; básicamente la POO simplifica la programación con la nueva filosofía y nuevos conceptos que tiene. La POO se basa en la división del programa en pequeñas unidades lógicas de código denominadas objetos. 1.2.
Programación Orientada a Objetos.
La programación orientada a objetos o POO (OOP ‐ Object Oriented Programming‐ según sus siglas en inglés) es un paradigma de programación que usa objetos y sus interacciones, para diseñar aplicaciones y programas informáticos. Está basado en varias técnicas, incluyendo herencia, abstracción, polimorfismo y encapsulamiento. Su uso se popularizó a principios de la década de los años 1990. En la actualidad, existe variedad de lenguajes de programación que soportan la orientación a objetos. Según el concepto vertido por Grady Booch, la POO se define de la siguiente manera: “La POO es un método de implementación en el que los programas se organizan como colecciones cooperativas de objetos, cada uno de los cuales representan una instancia de alguna clase, y cuyas clases son todas miembro de una jerarquía de clases unidas mediante relaciones de herencia” Así, se puede notar que la programación orientada a objetos tal cual su nombre lo indica trabaja exclusivamente con objetos y que cada uno de estos serán instancias de determinadas clases y que estas se relacionan unas con otras mediante la herencia. Ventajas de un lenguaje orientado a objetos. •
•
•
Fomenta la reutilización y extensión del código. Permite crear sistemas más complejos. Relacionar el sistema al mundo real. Dossier Programación III – Lic. Gladys Chuquimia Página 1 •
•
•
•
•
Facilita la creación de programas visuales. Construcción de prototipos Agiliza el desarrollo de software Facilita el trabajo en equipo Facilita el mantenimiento del software Lo interesante de la POO es que proporciona conceptos y herramientas con las cuales se modela y representa el mundo real tan fielmente como sea posible. 1.3.
Conceptos Fundamentales de POO.
1.3.1. Abstracción.
La abstracción se conoce también como el proceso de generalización en el que se quita todas las propiedades y acciones de un objeto extras que tenga el objeto para dejar solamente aquellas que sean necesarias. En otras palabras “abstracción” significa filtrar las propiedades y operaciones de un objeto hasta que queden solamente aquellas que necesitamos. Según Booch, la abstracción es la: “Supresión intencionada, u ocultamiento, de algunos detalles de un proceso o artefacto, con el objeto de destacar de manera más clara otros aspectos, detalles o estructuras”. 1.3.2. Encapsulación
Es la acción referida a “empaquetar” en una clase los datos (propiedades) y el código (métodos) que opera sobre estos datos. El encapsulamiento está directamente ligado a las características de caja negra que deben tener los programas OO, dado que cuando utilizamos un objeto no necesitamos conocer todos los detalles de la implementación; por lo cual es una buena práctica restringir el acceso a los datos y a la información interna de sus métodos, a esto se denomina ocultamiento de datos o encapsulación. 1.3.3. Objetos.
Existen muchas definiciones que se le ha dado al Objeto. Primero empecemos entendiendo que es un objeto del mundo real. Un objeto del mundo real es cualquier cosa que vemos a nuestro alrededor. Todo objeto del mundo real tiene 2 componentes: características y comportamiento. Por ejemplo, los automóviles tienen características (marca, modelo, color, velocidad máxima, etc.) y comportamiento (frenar, acelerar, retroceder, llenar combustible, cambiar llantas, etc.). Los Objetos de Software, al igual que los objetos del mundo real, también tienen características y comportamientos. Un objeto de software mantiene sus características en una Dossier Programación III – Lic. Gladys Chuquimia Página 2 o más "variables", e implementa su comportamiento con "métodos". Un método es una función o subrutina asociada a un objeto Un objeto puede representarse gráficamente de las siguientes maneras: Nombre del Objeto: Nombre de Clase Características ‐ Atributos Comportamiento ‐ Métodos a) Taylor
b) UML
1.3.4. Clases.
Es una descripción de un conjunto de objetos: Consta de Métodos y Datos. Es un TDA1 definido por el usuario que determina las estructuras de datos y sus operaciones asociadas. En POO, una clase no solo tiene el objetivo de categorizar una colección de elementos sino también el de servir como plantilla para crear objetos. Todos los objetos con estados similares y el mismo comportamiento se agrupan en clases. 1.3.5. Mensajes.
Todos los objetos se comunican entre sí mediante el paso de mensajes, y está referido a la ejecución de un método asociado con el objeto que lo llama. Luego para enviar mensajes se estipula el nombre del objeto y la acción que se requiere poner en ejecución. En este punto el método definido especifica cómo se ejecuta el mensaje. 1.3.6. Encapsulamiento.
Es la acción referida a “empaquetar” en una clase los datos (propiedades) y el código (métodos) que opera sobre estos datos. El encapsulamiento está directamente ligado a las características de caja negra que deben tener los programas OO, dado que cuando utilizamos un objeto no necesitamos conocer todos los detalles de la implementación; por lo cual es una buena práctica restringir el acceso a los datos y a la información interna de sus métodos, a esto se denomina ocultamiento de datos o encapsulación. 1
Tipo de Dato Abstracto
Dossier Programación III – Lic. Gladys Chuquimia Página 3 1.3.7. Herencia.
Se la define como el mecanismo que se emplea para crear nuevas clases a partir de clases existentes, que fomenta la reutilización de código. El principio en que basa la división de clases en la herencia es la jerarquía (características comunes). La herencia supone una clase base y una jerarquía de clases que contienen las clases derivadas de la clase base, es así como las clases derivadas pueden heredar todas las características de la clase pudiendo añadir cada una de estas subclases su propio código especial y datos propios. Las clases que heredan propiedades de una clase base pueden a su vez servir como definiciones base de otras clases; a su vez las jerarquías de clases se organizan en forma de árbol. Existen dos tipos de herencia: Simple y múltiple. En la herencia simple cada clase tiene como máximo una sola clase base. Polígono
Triangulo
Rectángulo
Hexágono En la herencia múltiple una clase derivada puede heredar todas las características asociadas con más de una clase base o superclase. Persona
Investigador
Profesor
Profesor Universitario
1.3.8. Polimorfismo.
Es la habilidad de enviar el mismo mensaje a objetos de diferentes clases y que cada objeto responda de una manera particular de acuerdo a su naturaleza. Así por ejemplo se puede enviar el mensaje abrir a los objetos: candado, maletín, periódico y al objeto puerta y todos ellos efectuarán una operación asociada a su naturaleza y se producirá una operación diferente, para cada uno de ellos, a pesar de que la acción tiene el mismo nombre. Dossier Programación III – Lic. Gladys Chuquimia Página 4 1.3.9. Función amiga.
Son aquellas funciones que han sido declaradas por la clase como amigas y que no son parte activa de la clase pero por su característica pueden trabajar con todos los datos y métodos de la clase de manera directa. 1.4.
Lenguajes Orientados a objetos.
Se tienen en el mercado una diversidad de lenguajes de programación orientado a objetos. El primer lenguaje de POO fue el SIMULA que emergió en el año 1964 y se deriva del ALGOL 60, donde tiene sus raíces, del cual toma el concepto de bloque e introduce el concepto de objeto. Luego se tiene al Smalltalk creado por Alan Kay que ha sido el inspirador de un gran número de lenguajes OO, entre los cuales se mencionan al Eiffel y al C++. Entre los programas más destacados OO que se emplean en la actualidad se mencionan al lenguaje C++, Delphi, JAVA, Object Cobol, Prolog++ y el Smalltalk. Ejercicio Propuesto. Realice un mapa mental que explique ¿Qué es la programación orientada a objetos? Identificando sus componentes. Dossier Programación III – Lic. Gladys Chuquimia Página 5 Unidad II Principios de la Programación Orientada a Objetos con Java 2.1.
Introducción.
En esta unidad se cubren los aspectos centrales que son fundamentales para trabajar con objetos, y diseñar un programa orientado a objetos en lenguaje Java. 2.2.
Historia de Java.
Java fue diseñado en 1990 por James Gosling, de Sun Microsystems, como software para dispositivos electrónicos de consumo. Curiosamente, todo este lenguaje fue diseñado antes de que diese comienzo la era World Wide Web, puesto que fue diseñado para dispositivos electrónicos como calculadoras, microondas y la televisión interactiva. Inicialmente Java se llamó Oak (roble en inglés), aunque tuvo que cambiar de denominación, debido a que dicho nombre ya estaba registrado por otra empresa. Se dice este nombre se le puso debido a la existencia de tal árbol en los alrededores del lugar de trabajo de los promotores del lenguaje. Bill Joy (cofundador de Sun y uno de los desarrolladores principales del sistema operativo Unix de Berckley) juzgó que Internet podría llegar a ser el campo adecuado para disputar a Microsoft su primacía en el terreno del software, y vio en Oak el instrumento idóneo para llevar a cabo estos planes.Para poder presentarlo en sociedad se tuvo que modificar el nombre de este lenguaje de programación y se tuvo que realizar una serie de modificaciones de diseño para poderlo adaptar al propósito mencionado. Así Java fue presentado en sociedad en agosto de 1995. Algunas de las razones que llevaron a Bill Joy a pensar que Java podría llegar a ser rentable son: 9 Java es un lenguaje orientado a objetos: Esto es lo que facilita abordar la resolución de cualquier tipo de problema. 9 Es un lenguaje sencillo, aunque sin duda potente. 9 La ejecución del código Java es segura y fiable: Los programas no acceden directamente a la memoria del ordenador, siendo imposible que un programa escrito en Java pueda acceder a los recursos del ordenador sin que esta operación le sea permitida de forma explícita. De este modo, los datos del usuario quedan a salvo de la existencia de virus escritos en Java. La ejecución segura y controlada del código Java es una característica única, que no puede encontrarse en ninguna otra tecnología. Dossier Programación III – Lic. Gladys Chuquimia Página 6 9 Es totalmente multiplataforma: Es un lenguaje sencillo, por lo que el entorno necesario para su ejecución es de pequeño tamaño y puede adaptarse incluso al interior de un navegador. 2.3.
Definición de Clases.
Las clases son abstracciones que representan a un conjunto de objetos con un comportamiento e interfaz común. Se define a una clase como: "un conjunto de cosas (físicas o abstractas) que tienen el mismo comportamiento y características... Es la implementación de un tipo de objeto (considerando los objetos como instancias de las clases)". Una clase no es más que una plantilla para la creación de objetos. Cuando se crea un objeto (instanciación) se ha de especificar de qué clase es el objeto instanciado, para que el compilador comprenda las características del objeto. Las clases presentan el estado de los objetos a los que representan mediante variables denominadas atributos. Cuando se instancia un objeto el compilador crea en la memoria dinámica un espacio para tantas variables como atributos tenga la clase a la que pertenece el objeto. Los métodos son las funciones mediante las que las clases representan el comportamiento de los objetos. En dichos métodos se modifican los valores de los atributos del objeto, y representan las capacidades del objeto (también se les denomina servicios). El elemento básico de la programación orientada a objetos en Java es la clase. Una clase define la forma y comportamiento de un objeto. Para crear una clase sólo se necesita un archivo fuente con la siguiente sintaxis: public class NombreDeLaClase{ //Atributos //Métodos } Un archivo de Java debe tener el mismo nombre que la clase que contiene, y se les suele asignar la extensión “.java”. Por ejemplo, el nombre del archivo que guarda la clase es: NombreDeLaClase.java. También se resalta que Java diferencia entre mayúsculas y minúsculas; por tanto, el nombre de la clase y el de archivo fuente han de ser exactamente iguales. Ejemplo de la creación de una clase public class Circulo{ private double x, y; // las coordenadas del centro public double r; // el radio // métodos que retornan la circunferencia y el área de circulo. Dossier Programación III – Lic. Gladys Chuquimia Página 7 public double area() {return 3.14159 * r * r;} } El control de acceso a los métodos está determinado por las palabras reservadas: 9
9
9
9
private private protected protected public Veamos la siguiente tabla: Clases Subclases Paquete Todas Prívate X private protected X X protected X X X Public X X X X Las X habilitan desde donde se tienen acceso a los miembros dato de la clase. De esta manera si los miembros de la clase son declarados de tipo private, sólo la clase que contiene al método puede llamarlo. Ahora bien, si se declaran como private protected, permite acceso a la clase y a cualquier subclase de la clase que quiera invocar al método. Si los miembros son declarados como protected, brinda acceso solo a los miembros de la clase, las subclases y todas las clases contenidas en el mismo paquete. Finalmente si son declarados de tipo public, todas las clases tienen acceso. 2.4.
Declaración de Objetos.
Los objetos del mundo real comparten dos características: Todos tienen estado y comportamiento. Los perros tienen estado (nombre, color, raza, hambriento) y comportamiento (ladrando, buscando, meneando la cola). Las bicicletas también tienen un estado (marcha actual, cadencia de pedaleo actual, velocidad actual) y comportamiento (cambio de marcha, cambio de cadencia de pedaleo, frenar). Identificar el estado y el comportamiento de los objetos del mundo real es una gran ayuda para empezar a pensar en términos de programación orientada a objetos, lo que se toma en cuenta en Java. Los objetos siempre son la instancia de una clase y utilizan memoria dinámica. Al crear un objeto se reserva espacio en memoria para sus variables a través de new (empleado en la definición de objeto) y se devuelve una referencia al objeto. La Sintaxis para declarar un objeto simple, es: NombreDeLaClase nombreObjeto = new NombreDeLaClase(); Dossier Programación III – Lic. Gladys Chuquimia Página 8 2.5.
Envío de Mensajes.
Se envía mensaje a través de los objetos, cuya sintaxis es la siguiente: Objeto.Metodo() Objeto.Atributo Tanto el método invocado como el atributo deben tener acceso público o tener los derechos para manipular estos miembros de la clase. 2.6.
Constructores.
Un constructor es un elemento de una clase cuyo identificador coincide con el de la clase correspondiente y que tiene por objetivo obligar a y controlar cómo se inicializa una instancia de una determinada clase, ya que el lenguaje Java no permite que las variables miembro de una nueva instancia queden sin inicializar. Además, a diferencia de los métodos, los constructores sólo se ejecutan cuando se declara un objeto, por única vez. Así, un constructor es una función que sirve para construir un nuevo objeto y asignar valores a sus miembros dato. Se caracteriza por: 9 Tener el mismo nombre que la clase 9 No devuelven valores 9 Pueden tener argumentos 9 Pueden existir más de un constructor para una clase Los constructores se declaran en el momento de definir la clase: public class A { int x, y; public A() { x=0; y=0; } // el constructor } El constructor puede tener argumentos. En este caso, se deben colocar los argumentos respectivos al crear el objeto: public class A { int x, y; public A(int ix, int iy) { x=ix; y=iy; } // el constructor … } Se pueden colocar varios constructores. Durante la creación de un objeto, se invoca aquel constructor que coincide totalmente con los argumentos dados: public class A { int x, y; public A() { x=0; y= 0; } public A(int ix, int iy) Dossier Programación III – Lic. Gladys Chuquimia Página 9 { x=ix; y=iy; } public A(A from) { x= from.x; y= from.y; } } Luego, las llamadas serían: A a1= new A(); //Es ejecutado el constructor sin argumentos previamente declarado. A a2= new A(1,2); //Se ejecuta el constructor con dos argumentos. A a3= new A(a2); //Ejecución del constructor con un argumento. 2.7.
Destructor.
Un destructor es un método que se invoca automáticamente cuando el objeto se destruye. JAVA no posee destructores, porque tiene recolección de basuras. Un destructor es un método que es ejecutado cada vez que se destruye (se elimina de RAM) un objeto, el objetivo de este método es el de eliminar toda la memoria que ocupó un objeto. En JAVA no es necesaria la definición de destructores, pues el mismo lenguaje se encarga de la eliminación y liberación de la memoria ocupada por un objeto, esto se realiza cada vez que un objeto pierde todas sus referencias. En resumen es un método de clase que sirve para realizar ciertas operaciones necesarias al dejar de existir un objeto, por ejemplo, cerrar conexiones de una comunicación, cerrar ficheros, etc. Java dispone de un elemento denominado recolector de basura (garbage collector) que se encarga de liberar memoria asignada a objetos que ya no se utilizan, aún así en ocasiones será necesario disponer de una función que realice operaciones adicionales a la mera liberación de memoria. Para este fin se crea un método, denominado finalize, con las siguientes características: protected void finalize() { … cuerpo del destructor } 2.8.
Arrays de Objetos.
Los objetos son variables y tienen las mismas capacidades y atributos que cualquier tipo de variables, por tanto es posible disponer objetos en un array. La sintaxis es exactamente igual a la utilizada para declarar y acceder al array. También disponemos de arrays bidimensionales. Declaración: NombreClase nombreObjeto[ ] = new NombreClase[20]; Dossier Programación III – Lic. Gladys Chuquimia Página 10 Inicialización: nombreObjeto[posición] = new NombreClase( ); Ejercicios Propuestos 1. Implementación la clase Dibujo, que muestre el dibujo que desee diseñar. 2. Implemente completamente la clase Pila. 3. Diseñe la clase círculo. 4. Elabore la clase matriz; que efectúe las operaciones principales y la generación de al menos dos matrices especiales. 5. Diseñe la clase vector, que realice las operaciones fundamentales que se desarrollan con vectores, además de incluir métodos de búsqueda y ordenación de vectores. Dossier Programación III – Lic. Gladys Chuquimia Página 11 Unidad III Sobrecarga 3.1.
¿Qué es sobrecarga?
La capacidad de realizar una acción diferente sin cambiar el nombre del método o el símbolo del operador, según la naturaleza del objeto. El lenguaje Java pone a nuestra disposición todas las herramientas necesarias que permiten efectuar la sobrecarga de funciones y nos dan en forma implícita la sobrecarga de operadores, que se considera en esta unidad. 3.2.
Sobrecarga de Funciones.
A través de esta propiedad dos o más funciones pueden tener el mismo nombre representado cada cual con un código diferente, que incide en la ejecución del método implementado; y es a la capacidad de realizar diferentes acciones bajo un mismo denominativo que se la conoce como sobrecarga de funciones. Una función sobrecargada se distingue básicamente por los siguientes aspectos: •
Tienen más de una definición para el mismo nombre de función. •
Cada definición difiere en el número de argumentos. •
Sus argumentos pueden contemplar diferentes tipos de datos. En Java se pueden sobrecargar todas las funciones que se definan, siguiendo las reglas mencionadas. La sobrecarga de funciones sigue la siguiente sintaxis: public class NombreDeLaClase{ // atributos // Métodos public TD MetodoSobrecargado() { //Instrucciones } public TD MetodoSobrecargado(TD arg1) { //Instrucciones } public TD MetodoSobrecargado(TD arg1, TD argN) { //Instrucciones } } Donde, TD representa a un tipo de dato válido, así porejemplo: int, float, etc ó void. Dossier Programación III – Lic. Gladys Chuquimia Página 12 Así por ejemplo, consideremos este programa: public class Encuentro { public void Saludo () { System.out.println (); System.out.println ("Hola Amig@"); } public void Saludo (String nom) { System.out.println ("Hola " + nom); } public void Saludo (String palabra, String nom) { System.out.println (palabra + nom); } public static void main (String[] args) { Encuentro obj = new Encuentro (); obj.Saludo (); obj.Saludo ("Susana"); obj.Saludo ("Bienvenida ", "Anita"); } } En la clase encuentro se observa con claridad que el método Saludo está dos veces sobrecargado, y que se ejecuta el mismo método de diferentes maneras según el parámetro que se envíe desde el programa principal. Finalmente se menciona que se consideró el proceso de sobrecarga cuando se efectúo la declaración de más de un constructor, dado que bajo el nombre de la clase se define más de una vez el constructor. Ejemplo: public class Encuentro { public Encuentro () { System.out.println ("Es un encuentro..."); } public Encuentro (String nom) { Dossier Programación III – Lic. Gladys Chuquimia Página 13 System.out.println ("Es un encuentro con " + nom); } public void Saludo () { System.out.println (); System.out.println ("Hola Amig@s"); } public void Saludo (String nom) { System.out.println ("Hola " + nom); } public void Saludo (String palabra, String nom) { System.out.println (palabra + nom); } public static void main (String[] args) { Encuentro obj1 = new Encuentro (); obj1.Saludo (); Encuentro obj2 = new Encuentro ("Susana"); obj2.Saludo ("Susana"); obj2.Saludo ("Que tal ", "Anita"); } } 3.3.
Sobrecarga de Operadores.
En Java prácticamente en forma explícita No existe. En los objetos String el operador + y += se permiten para la comparación de cadenas. El lenguaje Java sobrecarga la definición del operador + para incluir la concatenación de cadenas. El siguiente ejemplo utiliza + para concatenar la cadena "Contados ", con el valor de la variable contador y la cadena " caracteres.": System.out.print("Contados" + contador + "caracteres."); Dossier Programación III – Lic. Gladys Chuquimia Página 14 Esta operación automáticamente convierte el valor de contador a una cadena de caracteres, efectuándose de esta manera la sobrecarga. Ejercicios Propuestos 1. Diseña un programe que sobrecargue la función préstamo de la clase CuentaBancaria. 2. Implemente la clase matriz que sobrecargue la función de cargado de datos a la matriz, luego, efectúe la sobrecarga de constructor correspondiente. Dossier Programación III – Lic. Gladys Chuquimia Página 15 Unidad IV Herencia 4.1.
Herencia.
La verdadera potencia de la programación orientada a objetos radica en su capacidad para reflejar la abstracción que el cerebro humano realiza automáticamente durante el proceso de aprendizaje y el proceso de análisis de información. Es así que las personas percibimos la realidad como un conjunto de objetos interrelacionados. Dichas interrelaciones, pueden verse como un conjunto de abstracciones y generalizaciones que se han ido asimilando desde la niñez. Por eso se afirma que esta técnica se adecua mejor al funcionamiento del cerebro humano, al permitir descomponer un problema de cierta magnitud en un conjunto de problemas menores subordinados del primero. La capacidad de descomponer un problema o concepto en un conjunto de objetos relacionados entre sí, y cuyo comportamiento es fácilmente identificable, es muy útil en el desarrollo de programas informáticos. 4.2.
Jerarquía
La herencia es el mecanismo fundamental de relación entre clases en la orientación a objetos. Relaciona las clases de manera jerárquica; una clase padre, base o superclase sobre otras clases hijas, derivadas o subclases. Padre Hija1 Hija 2 Hija 1.1 Hija 1.2 Hija 1.1.1. 4.3.
Herencia Simple.
La herencia simple se realiza tomando una clase existente y derivando nuevas clases de ella tan solo una vez. Dossier Programación III – Lic. Gladys Chuquimia Página 16 En la herencia simple los descendientes de una clase heredan todas las variables y métodos que sus ascendientes hayan especificado como heredables, además de crear los suyos propios. La característica de herencia, nos permite definir nuevas clases derivadas de otra ya existente, que la especializan de alguna manera. Así logramos definir una jerarquía de clases, que se puede mostrar mediante la jerarquización. En todo lenguaje orientado a objetos existe una jerarquía, mediante la que las clases se relacionan en términos de herencia. En Java, el punto más alto de la jerarquía es la clase Object de la cual derivan todas las demás clases. Esquemáticamente se la representa así: Clase Padre Clase Hija1 Clase Hija N 4.4.
Constructores y Destructores en Herencia.
Los constructores y destructores de la clase base no se heredan por clases derivadas. En su lugar, los constructores de las clases hijas deben contener información de parámetros de los constructores de la clase base. La llamada a un constructor de una clase base se hace del mismo modo que las llamadas a los constructores de los miembros objeto. Se ejecutan los constructores definidos en la Clase Padre y luego de las hijas en orden de jerarquía, y en cuanto al destructor se ejecuta en forma inversa. 4.5.
Applets.
La clase Applet Java, de la cual han de heredar todos los programas Java que vayan a actuar como applets, es la única clase que contiene el paquete java.applet de la API de Java. Esta clase hereda de Object (como todas las clases Java), pero además hereda de Component y Container, que son dos clases del paquete gráfico AWT. Esto ya perfila las posibilidades gráficas de este tipo de aplicaciones Java. El ciclo de vida de un applet no es tan sencillo como el de una aplicación, que simplemente se ejecuta hasta que finaliza su método main(). La siguiente figura modeliza el ciclo de vida de una applet: Dossier Programación III – Lic. Gladys Chuquimia Página 17 Cada círculo representa una fase en el ciclo de vida de la applet. Las flechas representan transiciones y el texto representa la acción que causa la transición. Cada fase está marcada con una invocación a un método de la applet: void init(); Es invocado cuando se carga la applet. Aquí se suelen introducir las iniciaciones que la applet necesite. void start();Es invocado cuando la applet, después de haber sido cargada, ha sido parada (cambio de página Web, minimización del navegador,...), y de nuevo activada (vuelta a la página, restauración del navegador,...). Se informa a la applet de que tiene que empezar su funcionamiento. void stop(); Es invocado para informar a la applet de que debe de parar su ejecución. Así una applet que utilice threads, debería detenerlos en el código de este método. void destroy();Es invocado para informar a la applet de que su espacio está siendo solicitado por el sistema, es decir el usuario abandona el navegador. La applet debe de aprovechar este momento para liberar o destruir los recursos que está utilizando. void paint(); Es invocado cada vez que hay que el navegador redibuja la applet. Al crear una applet no es necesario implementar todos estos métodos. De hecho habrá applets que no los necesiten. Cuando un navegador carga una página Web que contiene una applet, suele mostrar en su parte inferior un mensaje como: initializing... starting... Esto indica que la applet, se está cargando: 1. Una instancia de la clase applet es creada. 2. La applet es iniciada, mediante su método init(). 3. La applet empieza a ejecutarse, mediante su método start(). Cuando el usuario se encuentra con una página Web, que contiene una applet y salta a otra página, entonces la applet se detiene invocando a su método stop(). Si el usuario retorna a la Dossier Programación III – Lic. Gladys Chuquimia Página 18 página donde reside la applet, ésta vuelve a ejecutarse nuevamente invocando a su método start(). Cuando el usuario sale del navegador la applet tiene un tiempo para finalizar su ejecución y hacer una limpieza final, mediante el método destroy(). Para incluir una applet en una página Web, una vez compilada la applet, debe incluirse entre el código HTML de la página Web una etiqueta <APPLET>, que como mínimo ha de presentar los siguientes tres parámetros: code: Especifica el URL del fichero de clase Java (*.class) que contiene la applet. width: Especifica la anchura inicial de la applet (en pixels). heigth: Especifica la altura inicial de la applet (en pixels). Así por ejemplo: <applet code="AppletDiagonal.class" width=200 height=200> </applet> 4.6.
Herencia Múltiple.
En la orientación a objetos, se consideran dos tipos de herencia, simple y múltiple. En el caso de la primera, una clase sólo puede derivar de una única superclase. Para el segundo tipo, una clase puede descender de varias superclases. En Java se trabaja con una Herencia Múltiple indirecta y con Interfases. Para indicar que una clase deriva de otra, heredando sus propiedades (métodos y atributos), se usa el término extends, como en el siguiente ejemplo: public class SubClase extends SuperClase { // Contenido de la clase } Por ejemplo, creamos una clase MiPunto3D, hija de la clase MiPunto: //Clase Padre o Superclase public class MiPunto{ int x, y; //Metodos } Dossier Programación III – Lic. Gladys Chuquimia Página 19 //Clase Hija o SubClase public class MiPunto3D extends MiPunto { int z; MiPunto3D( ) { x = 0; // Heredado de MiPunto y = 0; // Heredado de MiPunto z = 0; // Nuevo atributo } } La palabra clave extends se utiliza para decir que deseamos crear una subclase de la clase que es nombrada a continuación, en este caso MiPunto3D es hija de MiPunto. 4.7.
Limitaciones en la Herencia.
Todos los campos y métodos de una clase son siempre accesibles para el código de la misma clase. Para controlar el acceso desde otras clases, y para controlar la herencia por las subclase, los miembros (atributos y métodos) de las clases tienen tres modificadores posibles decontrol de acceso: public: Los miembros declarados public son accesibles en cualquier lugar en que sea accesible la clase, y son heredados por las subclases. private: Los miembros declarados prívate son accesibles sólo en la propia clase. protected: Los miembros declarados protectedson accesibles sólo para sus subclases Por ejemplo: public class Padre { // Hereda de Object // Atributos private int numeroFavorito, nacidoHace, dineroDisponible; // Métodos public int getApuesta () { return numeroFavorito; } protected int getEdad () { Dossier Programación III – Lic. Gladys Chuquimia Página 20 return nacidoHace; } private int getSaldo () { return dineroDisponible; } } public class Hija extends Padre { // Definición } En este ejemplo, un objeto de la clase Hija, hereda los tres atributos (numeroFavorito, nacidoHace y dineroDisponible) y los dos métodos (getApuesta() y getEdad() ) de la clase padre, y podrá invocarlos. Cuando se llame al método getEdad() de un objeto de la clase Hija, se devolverá el valor de la variable de instancia nacidoHace de ese objeto, y no de uno de la clase padre. Sin embargo, un objeto de la clase hija, no podrá invocar al método getSaldo() de un objeto de la clase padre, con lo que se evita que el hijo conozca el estado de la cuenta corriente de un padre. Ejercicios Propuestos 1. Represente la clase Animal mediante las relaciones de herencia, cree al menos dos clases derivadas. 2. Implemente la clase Teatro e incluya la representación de herencia múltiple. 3. Diseñe un programa en el que incluya relaciones de herencia, y constructores para representar a los arreglos. Dossier Programación III – Lic. Gladys Chuquimia Página 21 Unidad V Funciones Virtuales y Polimorfismo 5.1.
Introducción.
En programación orientada a objetos (POO), una función virtual o método virtual es una función cuyo comportamiento, al ser declarado "virtual", es determinado por la definición de una función con la misma cabecera en alguna de sus subclases. Este concepto es una parte muy importante del polimorfismo en la POO. El concepto de función virtual soluciona los siguientes problemas: En POO, cuando una clase derivada hereda de una clase base, un objeto de la clase derivada puede ser referido tanto como del tipo de la clase base como del tipo de la clase derivada. Si hay funciones de la clase base redefinidas por la clase derivada, aparece un problema cuando un objeto derivado ha sido referido como del tipo de la clase base. Cuando un objeto derivado es referido como del tipo de la base, el comportamiento de la llamada a la función deseado es ambiguo. Distinguir entre virtual y no virtual sirve para resolver este problema. Si la función en cuestión es designada "virtual", se llamará a la función de la clase derivada (si existe). Si no es virtual, se llamará a la función de la clase base. 5.2.
Ligadura.
Existen dos tipos de ligadura: Estática y dinámica. La ligadura estática (o temprana), consiste en realizar el proceso de ligadura en tiempo de compilación según el tipo declarado del objeto al que se manda el mensaje. La utilizan (en Java) los métodos de clase y los métodos de instancia que son privados o final (ya que estos últimos no pueden ser sobrescritos). En tanto que, la ligadura dinámica (o tardía), consiste en realizar el proceso de ligadura en tiempo de ejecución siendo la forma dinámica del objeto la que determina la versión del método a ejecutar. Se utiliza en todos los métodos de instancia de Java que no son privados ni final. Sirve para resolver conflictos entre Superclases y Subclases, cuando existe un conflicto entre un método de una superclase y un método de la subclase, el comportamiento correcto es que el método de la subclase sobrescriba al de la superclase. También significa que la forma dinámica del objeto determina la versión de la operación que se aplicara. Esta capacidad de las operaciones para adaptarse automáticamente a los objetos a los cuales se aplican es una de las propiedades más importantes de la orientación a objetos. Aunque puede variar de un lenguaje a otro, se presentan unas características comunes. Así, los métodos que necesitan ligadura dinámica son aquellos que pueden ser redefinidos. Por ejemplo, en Java, los métodos de clase y los métodos de instancia privados y/o finales no Dossier Programación III – Lic. Gladys Chuquimia Página 22 presentan ligadura dinámica. En Java, si no se especifica nada se entenderá que el método puede ser redefinido y por tanto debe presentar ligadura dinámica. 5.3.
Funciones Virtuales.
Una función virtual es miembro de una clase que se declara dentro de una clase base y se redefine en una clase derivada. Para crear una función virtual hay que preceder a la declaración de la función la palabra clave virtual. Debe tener el mismo tipo y numero de parámetros y devolver el mismo tipo. Cada redefinición de la función virtual en una clase derivada expresa el funcionamiento especifico de la misma con respecto a esa clase derivada. Cuando se redefine una función virtual en una clase derivada NO es necesaria la palabra virtual. 5.4.
Polimorfismo.
El polimorfismo es el uso de la misma definicion con diferentes tipos de datos, sobrecarga de operadores (ingl. operator overloading). En el siguiente ejemplo en el cual se crean cuatro programas se puede observar el polimorfismo: public abstract class Animal { public abstract void come (); } public class Lobo extends Animal { public void come () { System.out.println ("¡Yo como como un lobo!\n"); } } public class Pez extends Animal { public void come () { System.out.println ("¡Yo como como un pez!\n"); } } public class EjecutaEjemploHerenciaAnimalLoboPez { public static void main (String[] args) { Dossier Programación III – Lic. Gladys Chuquimia Página 23 Lobo unLobo = new Lobo (); Pez unPez = new Pez (); unLobo.come (); unPez.come (); } } 5.5.
Clases Abstractas
Hay ocasiones, cuando se desarrolla una jerarquía de clases en que algún comportamiento está presente en todas ellas pero se materializa de forma distinta para cada una. Por ejemplo, pensemos en una estructura de clases para manipular figuras geométricas. Podríamos pensar en tener una clase genérica, que podría llamarse FiguraGeometrica y una serie de clases que extienden a la anterior que podrían ser Circulo, Poligono, etc. Podría haber un método dibujar dado que sobre todas las figuras puede llevarse a cabo esta acción, pero las operaciones concretas para llevarla a cabo dependen del tipo de figura en concreto (de su clase). Por otra parte la acción dibujar no tiene sentido para la clase genérica FiguraGeometrica, porque esta clase representa una abstracción del conjunto de figuras posibles. Para resolver esta problemática Java proporciona las clases y métodos abstractos. Un método abstracto es un método declarado en una clase para el cual esa clase no proporciona la implementación (el código). Una clase abstracta es una clase que tiene al menos un método abstracto. Una clase que extiende a una clase abstracta debe implementar los métodos abstractos (escribir el código) o bien volverlos a declarar como abstractos, con lo que ella misma se convierte también en clase abstracta. Declaración e implementación de métodos abstractos Una clase abstracta y una función virtual se definen: abstract class FiguraGeometrica { abstract void dibujar(); } class Circulo extends FiguraGeometrica { void dibujar() { // codigo para dibujar Circulo } } La clase abstracta se declara simplemente con el modificador abstract en su declaración. Los métodos abstractos se declaran también con el mismo modificador, declarando el método pero sin implementarlo (sin el bloque de código encerrado entre {}). La clase derivada se declara e implementa de forma normal, como cualquier otra. Sin embargo si no declara e Dossier Programación III – Lic. Gladys Chuquimia Página 24 implementa los métodos abstractos de la clase base (en el ejemplo el método dibujar) el compilador genera un error indicando que no se han implementado todos los métodos abstractos y que, o bien, se implementan, o bien se declara la clase abstracta. Referencias y objetos abstractos Se pueden crear referencias a clases abstractas como cualquier otra. No hay ningún problema en poner: FiguraGeometrica figura; Sin embargo una clase abstracta no se puede instanciar, es decir, no se pueden crear objetos de una clase abstracta. El compilador producirá un error si se intenta: FiguraGeometrica figura = new FiguraGeometrica(); Esto es coherente dado que una clase abstracta no tiene completa su implementación y encaja bien con la idea de que algo abstracto no puede materializarse. Sin embargo utilizando el up‐casting visto en el capítulo dedicado a la Herencia si se puede escribir: FiguraGeometrica figura = new Circulo(. . .); figura.dibujar(); La invocación al método dibujarse resolverá en tiempo de ejecución y la JVM llamará al método de la clase adecuada. En este ejemplo se llamará al método dibujar de la clase Círculo. Ejercicios Propuestos 1. Implemente el polimorfismo en las clase Mueble, para el cual cree tres clases derivadas. 2. En la clase base Animal y las clases derivadas: Mamifero y Oviparo implemente el polimorfismo Dossier Programación III – Lic. Gladys Chuquimia Página 25 Unidad VI Plantillas y Tratamiento de Excepciones 6.1.
Plantillas.
Una plantilla es una forma que suele proporcionar una separación entre la forma o estructura y el contenido. Es un medio que permite guiar, portar o construir un diseño o esquema predefinido. Una plantilla agiliza el trabajo de reproducción de muchas copias idénticas o casi idénticas (que no tiene que ser tan elaborado, sofisticado o personal). Si se quiere un trabajo más refinado, más creativo, la plantilla no es sino un punto de partida, un ejemplo, una idea aproximada de lo que se quiere hacer. Desde luego la POO supuso un formidable avance del arsenal de herramientas de programación. Se toman en cuenta que las manipulaciones contienen un denominador común que se repite bajo apariencias diversas. Por ejemplo, la idea de ordenación "Sort" se repite infinidad de veces en la programación, aunque los objetos a ordenar y los criterios de ordenación varíen de un caso a otro. Alrededor de esta idea surgió un nuevo paradigma denominado programación genérica o funcional. La programación genérica está mucho más centrada en los algoritmos que en los datos y su postulado fundamental puede sintetizarse en una palabra: generalización. Significa que, en la medida de lo posible, los algoritmos deben ser parametrizados al máximo y expresados de la forma más independiente posible de detalles concretos, permitiendo así que puedan servir para la mayor variedad posible de tipos y estructuras de datos. Los expertos consideran que la parametrización de algoritmos supone una aportación a las técnicas de programación, al menos tan importante, como fue en su momento la introducción del concepto de herencia, y que permite resolver algunos problemas que aquella deja sin solución. Luego, las plantillas se basan en la programación orientada al dato razona del siguiente modo: representemos un tipo de dato genérico (por ejemplo int) que permita representar objetos con ciertas características comunes (peras y manzanas). También se definen operaciones que pueden aplicarse a este tipo (por ejemplo aritméticas) y sus reglas de uso, independientemente que el tipo represente peras o manzanas en cada caso. 6.2.
Excepciones.
En todo programa existen errores inesperados en tiempo de ejecución, y también errores que no consideramos debido a nuestra propia inexperiencia como programadores. Unos de estos errores ocurren por ejemplo, al intentar acceder a un elemento del arreglo que está fuera del Dossier Programación III – Lic. Gladys Chuquimia Página 26 límite de nuestro arreglo, o cuando intentamos acceder a un archivo inexistente, entre otros. Normalmente estos errores interrumpen el flujo de ejecución de nuestros programas, hasta el extremo de provocar la terminación del programa en forma inmediata. Java hace uso de las excepciones para poder controlar los errores en tiempo de ejecución. En Java, casi todo los tipos de errores que puedan surgir en tiempo de ejecución lanzan excepciones, es decir, cuando ocurre un error dentro de un método de Java, este método crea un objeto Exception, dicho objeto contiene información sobre la excepción, que incluye su tipo y el estado del programa cuando ocurrió el error. El sistema de ejecución es el responsable de buscar algún código para manejar el error. El manejo de excepciones en Java sigue una estructura como esta: try { //Codigo donde puede ocurrir un error } catch (ExcepcionA ex) { // Que se va a hacer en caso que se lanze una Excepcion A } catch (ExcepcionZ ex) { // Que se va a hacer en caso que se lanze una Excepcion Z } Dentro del bloque try{ } viene encerrado la parte del programa que se desea manejar sus excepciones. El código dentro de algún catch (TipoExcepcion e) se ejecuta en caso se que lanze una excepción TipoExcepcion o que pertenezca al grupo TipoExcepcion. El sistema de ejecución Java busca hacia atrás en la pila de llamadas para encontrar el método que esté interesado en manejar una excepción particular. Es decir si se lanza una excepción en el método, pero si no está interesado en manejar dicha excepción, entonces el sistema de ejecución Java ve quién lo llamó, entonces se regresa a y ve si está interesado en dicha excepción, y así consecutivamente hasta llegar al método principal de nuestra aplicación. En caso de no encontrar alguien que quiera manejarlo, comúnmente Java manda una lista de mensajes en nuestra ventana de consola, y en muchos casos se termina la ejecución de nuestro programa. Cuando manejamos excepciones, podemos manejar excepciones en forma específica (por ejemplo, usar un índice que está fuera de los límites de nuestro arreglo), o manejar una excepción de cierta categoría (por ejemplo, una excepción lanzada por mal uso de un arreglo de datos), o manejar todas las excepciones en su conjunto. Para el primer caso, es necesario este código catch(ArrayIndexOutOfBoundsException e){ }, para el segundo catch (ArrayException e){} y para el último catch (Exception e){ }. En la práctica no es recomendable hacer usar de manejadores de excepciones demasiado generales, como la del último caso. Las excepciones son parte de Java, y es muy común usarlos en las operaciones E/S, ya que es donde más probabilidad hay de que se lance una. Dossier Programación III – Lic. Gladys Chuquimia Página 27 6.3.
Lanzamiento de Excepciones.
Todos los métodos Java utilizan la sentencia throw para lanzar una excepción. Esta sentencia requiere un sólo argumento (un objeto Throwable). Si vemos el siguiente código de la función pop() cuyo propósito es sacar el elemento superior de la pila. public Object pop() throws EmptyStackException { Object obj; if (size == 0) throw new EmptyStackException(); obj = objectAt(size ‐ 1); setObjectAt(size ‐ 1, null); size‐‐; return obj; } El método pop() comprueba si la pila no está vacía. Si lo está, crea un nuevo objeto de la clase EmptyStackException y lo lanza, aunque en el método no se genere alguna excepción debido a lo bien validado que se encuentra, nosotros somos quienes lo lanzamos. Además por lógica, la clase EmpyStackException es una subclase de Thowable, ya que en cualquier otro caso, no se podría lanzar dicha excepción. Algo que se debe considerar aquí, es que en la declaración del procedimiento añade el siguiente código throws EmptyStackException, throws es una palabra reservada de java, y EmpyStackException es una subclase de Throwable. El uso de throws permite evitarnos la molestia de capturar las excepciones del tipo de excepciones indicadas después de esta palabra (las clases van separadas por coma), esto debido a que deja al sistema de ejecución Java que decida cuál sería la mejor opción en caso de que ocurriera una excepción de los tipos indicados. Ejercicios Propuestos 1. Implemente la clase Listas para que trabaje con distintos tipos de elementos. 2. Diseñe la clase Colas completamente para que sea genérica y trabaje con diferentes tipos de datos. Dossier Programación III – Lic. Gladys Chuquimia Página 28