Diferencia entre revisiones de «Prog. Ampliación POO»

De MediaWiki
Ir a la navegación Ir a la búsqueda
Línea 144: Línea 144:
 
==Lanzar excepciones==
 
==Lanzar excepciones==
  
 +
* Puede darse el caso de que en ciertas circunstancias queramos generar nosotros una excepción para informar a quien llama a un determinado método, de que los datos enviados no son los correctos (por ejemplo).
 +
 +
: Esto lo conseguimos 'lanzando' una excepción. Lanzar una excepción es equivalente a que se produzca una excepción en nuestro código y que provocará que nuestro programa 'pare' si no está implementado el try-catch correspondiente.
 +
 +
* Imaginemos que disponemos de una clase OperacionesIntervalos en la que disponemos de un método que calcula el número de números pares en un intervalo, siempre que este esté entre los números 1 y 1000.
 +
: El usuario podría enviar dos números fuera de los límites de dicho intervalo.
 +
: En ese caso, el método podría devolver un valor 'por defecto', como por ejemplo 0, pero este funcionamiento no es muy adecuado, ya que podría pensarse que el número de números pares es ese valor.
 +
: Para evitar este funcionamiento, podemos hacer que si los números del intervalo están fuera de los límites, provocaremos una excepción.
 +
: Para eso haremos uso de la [https://docs.oracle.com/javase/tutorial/essential/exceptions/throwing.html instrucción Throw].
  
  

Revisión del 11:38 6 dic 2017



Métodos get y set



Librerías

  • Vimos durante el curso que las clases que tienen algún tipo de relación entre ellas, deben de agruparse bajo un mismo 'paquete'.
  • Recordar también que las clases que se encuentran dentro de un mismo paquete tienen ciertos privilegios de acceso a los métodos/atributos del resto de las clases (modificar de acceso protected).
Por lo tanto podemos considerar los paquetes como una forma de 'limitar' el acceso a métodos y atributos definidos en las clases que se encuentran en el paquete (forma de encapsulación).


  • También vimos que para hacer uso de una clase definida en un paquete es necesario utilizar la orden import.


  • Una librería en un conjunto de clases relacionadas las cuales pueden estar definidas en diferentes paquetes, pero todas dentro del mismo 'archivo físico' el cual no es más que un archivo comprimido donde se encuentras las clases compiladas en sus correspondientes paquetes (directorios).
Por ejemplo, los paquetes que proporciona Java en el JDK y que ya vimos en un punto anterior de este manual se encuentran en el archivo /direc_instalación_jdk_o_jre/lib/rt.jar como podemos ver en la siguiente imagen:
Prog librerias 1.jpg





Lanzar excepciones


Delegación de excepciones

  • Vimos en teoría que las excepciones son errores no controlados por el usuario y que normalmente se producen en el envío de datos no adecuados a los métodos de una clase.
Por ejemplo, cuando intentamos acceder a una posición de una cadena que no existe: String nombre = "Angel"; char letra = nombre.charAt(55);
Sintácticamente el código es correcto, pero la ejecución dará un error en tiempo de ejecución que hará que se pare el programa.
Realizamos ejercicios en el manejo de las excepciones.
En esos ejercicios, la 'captura' de la excepción se realizaba en el propio método donde se podía producir el error.
Supongamos que tenemos una clase Lectura que se encarga de leer por teclado diferentes tipos de datos.
 1 package EntradaSalida;
 2 
 3 import java.util.Scanner;
 4 
 5 /**
 6  *
 7  * @author clase
 8  */
 9 public class Lectura {
10     private static Scanner sc = new Scanner(System.in);
11     
12     public static int leerNumeroEntero() {
13 
14         int numero = sc.nextInt();
15         return numero;
16     }
17 }


  • Si hacemos uso de esta clase, puede darse el caso de que el usuario no introduzca un número entero, produciéndose una excepción del tipo: java.util.InputMismatchException
En los ejercicios anteriores vimos que la excepción la podemos controlar nosotros dentro del método de la forma:
 1     public static int leerNumeroEntero() {
 2         int numero=0;
 3         try{
 4          numero = sc.nextInt();
 5         }
 6         catch(java.util.InputMismatchException ime){
 7             numero = 0;
 8         }
 9         return numero;
10     }
En este tipo de gestión de las excepciones, el método es el que se encarga de corregir el error del usuario, pero puede darse el caso de que no queramos que sea el método quien se encargue de eso, y que sea el que haga uso del método el que se preocupe de controlar el error y realizar las acciones adecuadas para subsanarlo.
  • Para ello, en la definición del método podemos indicar que tipos de excepciones va a lanzar, de la forma:
1 public void nombreMetodo() throws TipoExcepcion1[, TipoExcepcion2,....] {
2 
3 }
Como podemos ver podemos indicar que el método va a 'lanzar' diferentes tipos de excepciones, ya que puede ser que dentro del código se ejecuten sentencias que puedan producir diferentes tipos.
A esta forma de gestionar las excepciones se denomina Delegación de excepciones.


  • Aplicado a nuestro ejemplo:
1     public static int leerNumeroEntero() throws java.util.InputMismatchException{
2 
3         int numero = sc.nextInt();
4         return numero;
5     }


Ahora quien tiene que gestionar la excepción es la clase que haga uso del método leerNumeroEntero().
Lo podemos comprobar:
Prog excepciones 1.jpg
Ahora, cuando una clase hace uso de este método puede comprobar como va a lanzar una excepción y el tipo de excepción que puede lanzar.
Por lo tanto, el try-catch lo tendrá que hacer la clase que hace uso de este método:
 1 package proyectojava;
 2 
 3 import EntradaSalida.Lectura;
 4 /**
 5  *
 6  * @author clase
 7  */
 8 public class Principal2 {
 9     
10     public static void main (String arg[]){
11         
12       try {
13           System.out.printf("Numero entero:%d",Lectura.leerNumeroEntero());
14       }  
15       catch(java.util.InputMismatchException ime){
16           System.out.println("El dato introducido no es un número entero.");
17       }
18         
19     }
20     
21     
22 }




Lanzar excepciones

  • Puede darse el caso de que en ciertas circunstancias queramos generar nosotros una excepción para informar a quien llama a un determinado método, de que los datos enviados no son los correctos (por ejemplo).
Esto lo conseguimos 'lanzando' una excepción. Lanzar una excepción es equivalente a que se produzca una excepción en nuestro código y que provocará que nuestro programa 'pare' si no está implementado el try-catch correspondiente.
  • Imaginemos que disponemos de una clase OperacionesIntervalos en la que disponemos de un método que calcula el número de números pares en un intervalo, siempre que este esté entre los números 1 y 1000.
El usuario podría enviar dos números fuera de los límites de dicho intervalo.
En ese caso, el método podría devolver un valor 'por defecto', como por ejemplo 0, pero este funcionamiento no es muy adecuado, ya que podría pensarse que el número de números pares es ese valor.
Para evitar este funcionamiento, podemos hacer que si los números del intervalo están fuera de los límites, provocaremos una excepción.
Para eso haremos uso de la instrucción Throw.



Recursividad


Tipos de relaciones en POO


Clases abstractas

Ejercicios


Nota: Todos estos ejercicios están obtenidos de Internet. El sitio original está referenciado en su correspondiente enlace de la solución.



  • Declara una clase Persona que pueda ser instanciada con los atributos: nombre, apellidos, edad y estado civil (soltero/casado).
Declara una clase abstracta Legislador que herede de la clase Persona, con un atributo provinciaQueRepresenta (tipo String), partido político (tipo String) y despacho que ocupa (byte). Declara un método abstracto getCamaraEnQueTrabaja que devuelve una cadena String. Crea dos clases concretas que hereden de Legislador: la clase Diputado y la clase Senador que sobreescriban los métodos abstractos necesarios. Crea una lista de legisladores y muestra por pantalla la cámara en que trabajan haciendo uso del polimorfismo.
En todas las clases sobreescribe el método toString para que muestre la información.
Posible solución => Enlace 1


  • Declara una clase Persona que no pueda ser instanciada con los atributos: nombre, apellidos y edad.
Crea una clase Profesor que sea una subclase de la clase Persona, que tenga como atributos un idProfesor (numérico) y un método abstracto, importeNomina() que devolverá un número con decimales.
Crea una subclase de Profesor de nombre ProfesorTitular, en el que la nómina es igual a 30 horas lectivas multiplicadas por 43.20 euros cada hora.
Crea una subclase de Profesor de nombre ProfesorInterino, que tendrá como dato la fecha de inicio de la interinidad. Dicha fecha será enviada en el formato (dd/mm/yyyy) y tendrá un método devolverAños() que devolverá un número de tipo byte, que representará el número de años que lleva el Interino trabajando.
La nómina en el caso de los interinos es igual a 30 horas lectivas multiplicadas por 35.60 euros cada hora.
En todas las clases sobreescribe el método toString para que muestre la información.


Posible solución => Enlace 2.
Con respecto a la solución dada se tienen que considerar las siguientes diferencias:
  • Persona se pide que se defina como abstracta.
  • Las horas y precio por hora deben ser declaradas como constantes.
  • La fecha es enviada en forma de cadena y cuando se quiera calcular el número de meses, deberá de hacerse uso de la clase Calendar.


  • La empresa XYZ requiere una aplicación informática para administrar los datos de su personal.
Del personal se conoce: número de DNI, nombre, apellidos y año de ingreso.
Existen dos categorías de personal: el personal con salario fijo y el personal a comisión. Los empleados con salario fijo tienen un sueldo básico y un porcentaje adicional en función del número de años que llevan: menos de dos años salario base, de 2 a 3 años: 5% más; de 4 a 7 años: 10% más; de 8 a 15 años: 15% más y más de 15 años: 20% más. Los empleados a comisión tienen un salario mínimo que será constante para todos los empleados de este tipo e igual a 750.00€, un número de clientes captados y un monto por cada cliente captado. El salario se obtiene multiplicando los clientes captados por el monto por cliente, si el salario por los clientes captados no llega al salario mínimo, cobrará esta cantidad.
Se contará con una clase padre Empleado de la cual no se podrán crear objetos y de la que heredan las clases EAsalariado y EComision. En todas las clases debe haber un constructor con parámetros para todos los atributos y otro vacío. En todos deben crearse los getters and setters correspondientes. Empleado contará con un método imprimir() y un método obtenerSalario().
Se creará una clase gestora y en el método main se creará un vector con los siguientes objetos:
Javier Gómez, DNI: 569587A, desde 2008, salario fijo base = 1225.00€.
Eva Nieto, DNI: 695235B, desde 2010, 179 clientes captados a 8.10€ cada uno.
José Ruiz, DNI: 741258C, desde 2012, 81 clientes captados a 7.90€ cada uno.
María Núñez, DNI: 896325D, desde 2013, salario fijo base = 1155.00€.
Los dos primeros se crearán utilizando el constructor con todos los parámetros y los dos últimos con el constructor vacío y utilizando los setters adecuados.
Desde el método main se llamará a estos otros dos métodos:
sueldoMayor(): Dado un array de objetos Empleado muestra el nombre, apellido y salario del que más cobra.
mostrarTodos(): Dado un array de objetos Empleado lo recorre imprimiendo los datos de todos ellos.
Posible solución => Enlace 3

Interfaces


UML













-- Ángel D. Fernández González -- (2017).