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

De MediaWiki
Ir a la navegación Ir a la búsqueda
Línea 54: Línea 54:
 
: Imaginemos que disponemos de un objeto de la clase Scanner para leer datos del teclado. Supongamos que en un momento dado, dentro de nuestro código 'cerramos' el objeto (llamando al método close) y después intentamos leer del teclado. Esto daría consigo que se lanzaría la excepción 'IllegalStateException' (que derive de RunTimeException). El compilador de Java no nos obliga a tener un try..catch ya que es un fallo de programación.
 
: Imaginemos que disponemos de un objeto de la clase Scanner para leer datos del teclado. Supongamos que en un momento dado, dentro de nuestro código 'cerramos' el objeto (llamando al método close) y después intentamos leer del teclado. Esto daría consigo que se lanzaría la excepción 'IllegalStateException' (que derive de RunTimeException). El compilador de Java no nos obliga a tener un try..catch ya que es un fallo de programación.
  
: A diferencia de las excepciones 'checked' las cuales se lanzan no porque el programa esté mal, sino porque vienen datos inadecuados o situaciones ajenas al programa, como por ejemplo, intentar abrir un fichero que no existe o intentar leer un número y que el usuario introduzca una cadena. Este de excepciones sí que son necesarias capturarlas para que el programa funcione con normalidad.
+
: A diferencia de las excepciones 'checked' las cuales se lanzan no porque el programa esté mal, sino porque vienen datos inadecuados o situaciones ajenas al programa, como por ejemplo, intentar abrir un fichero que no existe. Este tipo de excepciones sí que son necesarias capturarlas para que el programa funcione con normalidad.
  
  

Revisión del 20:00 9 ene 2018



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





  • Ejercicio propuesto:
  • Modifica el ejercicio del programador novato y crea una librería en la que se encuentren las clases Vehiculo, Coche y Transporte (que están dentro del paquete 'transportes').
Crea el archivo jar y después haz uso del mismo dentro del proyecto donde se encuentra la clase Principal.
  • Añade a la misma librería las clases creadas en el ejercicio final y que se encuentran dentro del paquete 'material.deportivo'.
Modifica el proyecto donde se encuentra la clase Principal para que haga uso de la librería.



Excepciones

  • Podéis consultar la jerarquía de excepciones en este gráfico.
  • Nosotros trabajamos sobre las que derivan de la clase Exception, ya que las que derivan de la clase Error son errores de la máquina virtual de Java (por ejemplo que no disponga de memoria) y esos errores no son gestionados por las aplicaciones desarrolladas por nosotros.


  • Heredando de la clase Exception tenemos la clase La clase RunTimeException. Este tipo de excepción junto a todas sus subclases, son denominadas excepciones de tipo 'unchecked'. A diferencia de las otras, no se obliga a poner un try...catch cuando una instrucción lanza es tipo de excepción.
Esto es debido a que estas excepciones son lanzadas cuando hay un problema en el código del programa (el programa está mal hecho) por lo que normalmente querremos que el programa acabe.
Imaginemos que disponemos de un objeto de la clase Scanner para leer datos del teclado. Supongamos que en un momento dado, dentro de nuestro código 'cerramos' el objeto (llamando al método close) y después intentamos leer del teclado. Esto daría consigo que se lanzaría la excepción 'IllegalStateException' (que derive de RunTimeException). El compilador de Java no nos obliga a tener un try..catch ya que es un fallo de programación.
A diferencia de las excepciones 'checked' las cuales se lanzan no porque el programa esté mal, sino porque vienen datos inadecuados o situaciones ajenas al programa, como por ejemplo, intentar abrir un fichero que no existe. Este tipo de excepciones sí que son necesarias capturarlas para que el programa funcione con normalidad.




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.


  • Si un método no gestiona las excepciones que puedan producirse, el error irá desplazándose hasta el método que realizó la llamada y así sucesivamente hasta llegar a un método que gestione el error y en el caso de que no exista, llegará hasta la máquina virtual de Java, que detendrá la ejecución del programa.


  • En este manual 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 }


Ejercicios propuestos

  • Podéis responder a algunas de las preguntas planteadas en este enlace.




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.
El usuario podría enviar los números del intervalo en orden contrario, enviando primero el número mayor, por ejemplo...
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 o si el orden no es el adecuado, provocaremos una excepción.
Para eso haremos uso de la instrucción throw.


  • Throw lleva asociado la instanciación de un tipo de excepción (recordar que las excepciones son clases). Dependiendo del tipo de error podremos lanzar un tipo de excepción.
Para lanzar una excepción podemos poner: throw new TipoExcepcion(mensaje);
Mensaje es una cadena en la que podemos indicar cual fue el motivo de la excepción.
  • Aplicado a nuestro ejemplo:
 1 package varios;
 2 
 3 /**
 4  *
 5  * @author clase
 6  */
 7 public class OperacionesIntervalos {
 8     public static final int LIMITE_INFERIOR = 1;
 9     public static final int LIMITE_SUPERIOR = 1000;
10 
11     public static int obtenerNumerosParesIntervalo(int inferior, int superior) throws IndexOutOfBoundsException{
12         int numPares = 0;
13         
14         if (inferior > superior){
15             throw new IndexOutOfBoundsException("Limite inferior no puede ser menor que el superior");
16         }
17         if (inferior < LIMITE_INFERIOR || superior > LIMITE_SUPERIOR){
18             throw new IndexOutOfBoundsException("Los límites del intervalo se pasan de los valores permitidos");
19         }
20         for(int cont=inferior;cont<=superior;cont++){
21             if (cont%2==0){
22                 numPares++;
23             }
24         }
25         return numPares;
26     }
27     
28 }
  • Línea 11: Indicamos que este método va a poder lanzar una excepción del tipo 'IndexOutOfBoundsException'
  • Línea 15: En caso de que el número que indica el límite inferior del intervalo, tenga un valor mayor que el segundo número, lanzaremos una excepción del tipo indicado, enviando un texto explicativo del motivo de la excepción.
  • Línea 18: Igual que en la línea 11 pero esta vez debido a que nos pasamos de los límites que puede tener el intervalo.


 1 package proyectojava;
 2 
 3 import varios.OperacionesIntervalos;
 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 de pares entre 2 y 50:%d",OperacionesIntervalos.obtenerNumerosParesIntervalo(2,50));
14           System.out.printf("Numero de pares entre 30 y 5:%d",OperacionesIntervalos.obtenerNumerosParesIntervalo(30,5));
15       }  
16       catch(IndexOutOfBoundsException iobe){
17           System.out.println("\nEl intervalo no es correcto");
18           System.out.println("Mensaje de la excepción:" + iobe.getMessage());
19       }
20       try {
21           System.out.printf("Numero de pares entre -10 y 50:%d",OperacionesIntervalos.obtenerNumerosParesIntervalo(-10,50));
22       }  
23       catch(IndexOutOfBoundsException iobe){
24           System.out.println("\nEl intervalo no es correcto");
25           System.out.println("Mensaje de la excepción:" + iobe.getMessage());
26       }
27         
28     }
29 }
  • Línea 14: Esta llamada va a provocar que se lance una excepción, ya que el primer número es mayor que el segundo.
  • Línea 18: Podemos recoger el texto que viene con la excepción.
  • Línea 21: Esta llamada va a provocar que se lance una excepción, ya que el intervalo no está entre 1 y 1000.
  • Línea 25: Podemos recoger el texto explicativo de la excepción.


  • Recordar que un método puede lanzar múltiples excepciones, teniendo que indicar los tipos de excepciones que lanza en la definición del método, después de la palabra clave throws separadas por comas.


Lanzar excepciones propias

  • Puede suceder que el error que estamos controlando no tenga una correspondencia con alguno de los tipos de excepción de Java.
Por ejemplo, en el caso anterior, lanzamos una excepción de tipo IndexOutOfBoundsException, que normalmente se emplea cuando intentamos acceder a una posición de un array que no existe.
En el caso anterior, podríamos darla por 'buena' en el caso de que intentemos calcular los números pares fuera del intervalo 1 - 1000, pero en el caso de que enviemos los números del intervalo en orden diferente, no se ajustaría al significado del tipo de excepción.
  • Es en estos casos en los que podemos 'crear' nuestras propias clases de excepciones.
Recordar que una excepción es una clase, por lo tanto, lo que tenemos que hacer es definir una clase que derive de la clase base 'Exception' y que tenga un constructor con un parámetro de tipo String, que será el mensaje que guardará la excepción (esto si queremos que tenga dicha funcionalidad).
1 public class MiExcepcion{
2    
3    public MiExcepcion(String msg){
4        super(msg);
5    }
6 
7 }
Como vemos, en el constructor llamaremos al constructor de la clase Exception enviando ese mimos mensaje.


  • Apliquemos esto al ejemplo anterior:

Clase IncorrectoIntervaloException (representa el tipo de excepción personalizado)

1 package varios;
2 
3 public class IncorrectoIntervaloException extends Exception{
4     
5     public IncorrectoIntervaloException(String msg){
6         super(msg);
7     }
8     
9 }


Clase OperacionesIntervalos

 1 package varios;
 2 
 3 /**
 4  *
 5  * @author clase
 6  */
 7 public class OperacionesIntervalos {
 8     public static final int LIMITE_INFERIOR = 1;
 9     public static final int LIMITE_SUPERIOR = 1000;
10 
11     public static int obtenerNumerosParesIntervalo(int inferior, int superior) throws IndexOutOfBoundsException,IncorrectoIntervaloException{
12         int numPares = 0;
13         
14         if (inferior > superior){
15             throw new IncorrectoIntervaloException("Limite inferior no puede ser menor que el superior");
16         }
17         if (inferior < LIMITE_INFERIOR || superior > LIMITE_SUPERIOR){
18             throw new IndexOutOfBoundsException("Los límites del intervalo se pasan de los valores permitidos");
19         }
20         for(int cont=inferior;cont<=superior;cont++){
21             if (cont%2==0){
22                 numPares++;
23             }
24         }
25         return numPares;
26     }
27     
28 }
  • Línea 15: Aquí lanzamos la excepción personalizada. Fijarse que no hace falta importar la clase de la excepción ya que en el ejemplo se encuentra en el mismo paquete.


Clase Principal2

 1 package proyectojava;
 2 
 3 import varios.OperacionesIntervalos;
 4 import varios.IncorrectoIntervaloException;
 5 /**
 6  *
 7  * @author clase
 8  */
 9 public class Principal2 {
10     
11     public static void main (String arg[]){
12         
13       try {
14           System.out.printf("Numero de pares entre 2 y 50:%d",OperacionesIntervalos.obtenerNumerosParesIntervalo(2,50));
15           System.out.printf("Numero de pares entre 30 y 5:%d",OperacionesIntervalos.obtenerNumerosParesIntervalo(30,5));
16       }  
17       catch(IndexOutOfBoundsException iobe){
18           System.out.println("\nMensaje de la excepción:" + iobe.getMessage());
19       }
20       catch(IncorrectoIntervaloException iie){
21           System.out.println("\nMensaje de mi excepción:" + iie.getMessage());
22       }
23       try {
24           System.out.printf("%nNumero de pares entre -10 y 50:%d",OperacionesIntervalos.obtenerNumerosParesIntervalo(-10,50));
25       }  
26       catch(IndexOutOfBoundsException iobe){
27           System.out.println("\nMensaje de la excepción:" + iobe.getMessage());
28       }
29       catch(IncorrectoIntervaloException iie){
30           System.out.println("\nMensaje de mi excepción:" + iie.getMessage());
31       }
32         
33     }
34 }
  • Línea 4: Importamos la clase del nuevo tipo de excepción.
  • Línea 20: Capturamos el tipo de excepción personalizada.



printStackTrace()

  • Este método lo encontramos dentro de cualquier objeto que pertenezca a una clase de excepción.
Cuando realizamos el catch, indicamos el nombre del objeto que va a capturar el tipo de excepción indicado.
Ese objeto tiene la información del error, que la obtenemos con la llamada al método 'getMessage()' y también podemos obtener el origen del error con la llamada a 'printStackTrace()'.


  • Como comentamos anteriormente, cuando se produce una excepción el error se va propagando entre los métodos hasta llegar a uno que gestione el error (tenga el catch).
Con la llamada a printStackTrace, podemos saber en qué método se originó la excepción.


  • Veamos un ejemplo:

Clase MiClase

 1 package proyectojava;
 2 
 3 /**
 4  *
 5  * @author clase
 6  */
 7 public class MiClase {
 8     
 9     public void metodo1()  {
10         
11         System.out.println("Método 1 se ejecuta");
12         metodo2();
13         
14     }
15     public void metodo2()  {
16         
17         System.out.println("Método 2 se ejecuta");
18         metodo3();
19         
20     }
21     public void metodo3()  {
22         
23         System.out.println("Método 3 se ejecuta");
24         System.out.println("Método 3 lanza excepción");
25 
26         String cad="";
27         char car = cad.charAt(10);
28     }
29     
30 }
  • Línea 27: Como vemos esta clase llama a tres métodos y el último de ellos provoca una excepción.


Clase Principal3

 1 package proyectojava;
 2 
 3 /**
 4  *
 5  * @author clase
 6  */
 7 public class Principal3 {
 8     
 9     public static void main (String arg[]){
10     
11         MiClase miclase = new MiClase();
12         try{
13             miclase.metodo1();
14         }
15         catch(Exception e){
16             System.out.println("CAPTURANDO EXCEPCION:" + e.getMessage());
17             e.printStackTrace(System.err);
18         }
19     }
20 
21 }
  • En la línea 17 mostramos la traza de errores, es decir, desde donde se produce el error y como se va 'propagando' hasta llegar a un método que gestione el error.
En este ejemplo estamos utilizando la salida de errores (System.err) y por eso la información sale en color rojo. Podríamos ponerla en la salida estándar con 'System.out'.


Prog excepciones 2.jpg


  • Normalmente lo emplearemos cuando necesitemos depurar un programa para ver el origen de un error.




Ejercicios propuestos

Ejercicio 1

  • Crea una clase de nombre MiCadena.
Cuando se instancie dicha clase, se podrá mandar como dato una cadena que se guardará en un atributo de la clase.
Dispondrá de los siguientes métodos:
  • concatenar(String dato): concatenerá a la cadena guardada la cadena del parámetro.
  • devolverLong(): Intentará convertir la cadena guardada a un long y devolverlo. Podrá lanzar una excepción 'ConversionNumeroException'.
  • convertirCadenaNumero(): analizará la cadena buscando dígitos numéricos. En caso de encontrarlo, guardará en la cadena los dígitos encontrados descartando el resto. Por ejemplo: "A12ddddd2423" dará como resultado: "122423". En caso de no encontrar números lanzará la excepción 'NoNumeroException'.
  • devolverPosicionCadena(int pos): Devolverá el caracter encontrado en la posición indicada. Podrá lanzar un IndexOutOfBoundsException.
  • compararNumero(int valor): Comparará el número enviado con el número guardado en la cadena. Si es mayor valor, devolverá false, en caso contrario devolverá true. Debes hacer uso del método devolverEntero() y la excepción no la debes gestionar tú.
  • asignarValor(String cadena): Guardará la cadena enviada como parámetro sustituyendo a la cadena guardada previamente. En caso de que la cadena a enviar sea vacía o tenga el valor null, lanzará una excepción de tipo ValorCadenaException.
  • Sobreescribe el método toString() para que muestre la cadena en caso de 'imprimir' el objeto.


Crea una clase Principal y haz una llamada a cada uno de los métodos anteriores.


Posible solución Excepciones Ejercicio 1




Ejercicio 2

  • Crea una clase de nombre Lectura.
Todos los métodos podrán ser llamados sin necesidad de instanciar la clase.
Define un único objeto Scanner.
La entrada de datos se realizará en cada uno de los métodos.
Crea los siguientes métodos:
  • leerEntero(): debe devolver un número entero entre 1 y 100. En caso de que no introduzca un número se lanzará la excepción 'InputMismatchException' y en el caso de que no esté entre los límites (valores entre 1 y 100), lanzará la excepción 'LimitesException' (es definida por el usuario). En cualquier otro caso lanzará la excepción Exception.
  • leerCadena(): debe devolver una cadena de texto introducida por teclado. Dicha cadena de texto no puede ser vacía. Las excepciones deben ser controladas por el que realiza la llamada.
  • leerBooleano(): debe devolver un booleano introducido por teclado. Las excepciones deben ser controladas por el que realiza la llamada.
Crea una clase Principal y haz una llamada a cada uno de los métodos anteriores.




Clases abstractas


Aclaraciones

  • En ciertos apuntes viene indicado que las clases abstractas no pueden tener métodos privados ni métodos de clase. Esto no es cierto. Lo que no puede ser es que se declaren métodos abstractos privados ya que no podrían ser implementados por las subclases.
La única diferencia entre una clase 'normal' y una clase 'abstracta' es que no se pueden instanciar objetos de una clase abstracta.
A mayores una clase abstracta puede contener métodos abstractos que 'obligan' a que las subclases implementen su código.


  • Para que una clase sea abstracta no tiene que tener un método abstracto. Puede ser abstracta indicando la palabra reservada 'abstract' en su definición. Esto también viene mal indicado en ciertos blogs de internet.


  • La utilización de clases abstractas la podemos delimitar a dos situaciones:
  • Cuando tenemos una relación de herencia en la que no queremos que se pueda crear objetos de la superclase, sino que aprovechamos las características de la herencia para hacer que el código de ciertos métodos y atributos comunes no se repitan en cada una de las 'subclases'. En este caso haríamos la superclase 'abstract'.
  • Cuando tenemos una relación de herencia y queramos definir una funcionalidad que es común para todas las subclases, pero cuya implementación es diferente en cada una de ellas. En este caso haremos abstracto el método, obligándonos a definir como abstracta a la clase.


  • Podemos definir 'variables' del tipo de la clase abstracta y podremos con dicha variable referenciar a objetos que pertenezcan a clases que deriven de la clase abstracta. En este caso haremos uso del polimorfismo al llamar a algún método que esté definido en la clase abstracta.


  • Ejemplo de uso de clases abstractas:
  • En nuestro ejercicio del programador novato, la clase Vehiculo podría ser una clase abstracta.
  • Si tenemos una clase Figura, podemos declarar un método abstracto de nombre 'dibujar'. La implementación de dicho método será diferente en cada subclase. Subclases podrían ser Cuadrado, Circulo, Triangulo,..
  • Si tenemos una clase Intrumento con un método 'tocar', dicho método será abstracto y tendremos que implementar el código concreto en cada subclase, como podrían ser Violin, Piano, Viola,...



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 (harás uso del polimorfismo).
En todas las clases sobreescribe el método toString para que muestre la información de cada clase e 'imprime' cada uno de los legisladores.
Para crear una variable de tipo array en la que cada elemento sea un objeto de una clase debemos de definirlo de la forma: array miembros[] = { new Clase(), new Clase()};
Recuerda que para hacer referencia a un elemento de un array debemos de indicar su posición de la forma nombre_array[pos] siendo pos un número que va desde 0 (posición inicial del array) hasta nombre_array.length - 1
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


Recursividad


Tipos de relaciones en POO



UML













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