Clases abstractas e interfaces

Clase abstracta:

package com.trifulcas.clases;


// Clase abstracta. Es una clase que puede tener de todo como un clase normal
// Pero no puede ser instanciada
// Con frecuencia las clases abstractas incorporan métodos abstractos
abstract public class Animal {
	String nombre;
	// Esto es un método abstracto
	// Significa que sólo definimos parámetros de entrada y salida
	// No especificamos funcionalidad en código
	// Obligar a todas las clases derivadas a implementar este método
	abstract void sonido();
	// Esto es un método normal y corriente
	public void saludo() {
		System.out.println("Me llamo "+nombre);
	}
	
}

class Perro extends Animal{
	public void sonido() {
		System.out.println("Guau");
	}
	public void aullido() {
		System.out.println("Auuuuuu");
	}

}
class Gato extends Animal{
	public void sonido() {
		System.out.println("Miau");
	}
	public void ronroneo() {
		System.out.println("Rrrrrr");
	}
}
class Pato extends Animal{
	public void sonido() {
		System.out.println("CuaCua");
	}
}
class Ornitorrinco extends Animal{

	public void sonido() {
		System.out.println("Bidiji");
	}
}

class Caballo extends Animal{

	@Override
	public void sonido() {
		System.out.println("Brrr");
		
	}
	
}

Interfaces:

package com.trifulcas.clases;


// Definiendo un interface con un método
interface Audio {
	// Este método es como un método abstracto de una clase abstracta
	// Las clases que implementen este interfaz deben implementar el método
	void sonido();
}

interface Movimiento{
	void acelerar();
	void frenar();
}


class Automovil implements Audio,Movimiento {

	@Override
	public void sonido() {
		System.out.println("brum brum");
	}

	@Override
	public void acelerar() {
		// TODO Auto-generated method stub
		
	}

	@Override
	public void frenar() {
		// TODO Auto-generated method stub
		
	}

}

class Monociclo  implements Audio  {

	@Override
	public void sonido() {
		System.out.println("Dring dring");

	}

}

class Avion implements Audio{

	@Override
	public void sonido() {
		// TODO Auto-generated method stub
		
	}
	
}
package com.trifulcas.clases;

public class Instrumento implements Audio {

	public Instrumento() {
		// TODO Auto-generated constructor stub
	}

	@Override
	public void sonido() {
		System.out.println("Tarán");
	}

}

Un interfaz suelto con herencia:

package com.trifulcas.clases;

public interface Financiero {
	// Métodos que se tienen que implementar en aquellas clases
	// que implementen este interfaz
	// Y con los mismos parámetros de entrada y salida
	double interes();
	double irpf(int importe);
}

interface Bolsa extends Financiero{
	void compra();
}

Clases que implementan ese interfaz:

package com.trifulcas.clases;

// Al implementar 'Financiero' estoy obligado a definir los métodos
// incluídos en el interfaz: interes e irpf
public class Banco implements Financiero {
	private int saldo;

	public Banco() {
		saldo = 9000;
	}

	@Override
	public double interes() {
		if (saldo < 500) {
			return 0.5;
		} else {
			return 0.3;
		}
	}

	@Override
	public double irpf(int importe) {

		return 0.12;
	}

}

package com.trifulcas.clases;


// Lo mismo que en Banco. Pero 'Sueldo' y 'Banco' son dos clases que
// no están relacionadas por herencia
public class Sueldo implements Financiero {

	public Sueldo() {
		// TODO Auto-generated constructor stub
	}

	@Override
	public double interes() {
		// TODO Auto-generated method stub
		return 0;
	}

	@Override
	public double irpf(int importe) {
		// TODO Auto-generated method stub
		return 0.15;
	}

}

package com.trifulcas.clases;

abstract public class Broker implements Bolsa {

	public Broker() {
	}
	abstract void comision();
}


// Esta clase hereda:
// 1.- El contrato de el método abstracto comision de su clase madre
// 2.- El contrato del interfaz Bolsa que ha adquirido la madre
// 3.- El contrato del interfaz Financiero que ha adquirido Bolsa por extenderlo
class WallStreet extends Broker{

	@Override
	public void compra() {
		// TODO Auto-generated method stub
		
	}

	@Override
	public double interes() {
		// TODO Auto-generated method stub
		return 0;
	}

	@Override
	public double irpf(int importe) {
		// TODO Auto-generated method stub
		return 0;
	}

	@Override
	void comision() {
		// TODO Auto-generated method stub
		
	}
	
}



Uso en el programa:

package com.trifulcas.clases;

import com.trifulcas.ejercitos.Ejercito;

public class ProbarClases {

	public static void main(String[] args) {
		
		Animal[] granja= {new Perro(),new Gato(),new Pato()};
		Audio[] parque= {new Automovil(), new Monociclo(),new Instrumento()};
		
		Financiero[] empresa= {new Banco(),new Sueldo(),new Banco()};
		
		Perro p=new Perro();
		
		
		
		for(Financiero f:empresa) {
			System.out.println(f.interes());
		}
		
		Banco b=new Banco();
		Sueldo s=new Sueldo();
		
		System.out.println(importe(b,1000));
		System.out.println(importe(s,2000));
		
		Movimiento miCarro=new Automovil();
		
		for(Animal animal:granja) {
			animal.sonido();
		}
		for(Audio vehiculo:parque) {
			vehiculo.sonido();
		}
		
		Automovil auto=new Automovil();
		Instrumento violin=new Instrumento();
		
		repetir(auto,3);
		repetir(violin,8);
	}
	
	// El parámetro 'elemento' debe ser de una clase que implemente el
	// interfaz 'Financiero' obligatoriamente yo sé que ese parámetro
	// tendrá definidos los métodos 'interes' y 'irpf'
	public static double importe(Financiero elemento, double importe) {
		return elemento.interes()*importe;
	}
	
	public static void repetir(Audio elemento, int veces) {
		for(int i=0;i<veces;i++) {
			elemento.sonido();
		}
	}
}

Ejercicio Clases V

Vamos a usar la clase que hemos hecho dentro de un programa.

El programa nos va a decir lo siguiente:

Bienvenido al simulador. Vamos a crear un ejército
¿Cuantos soldados quieres?
¿Cuantos lanceros quieres?
¿Cuantos capitanes quieres?

Creado el ejército con N soldados, N lanceros y N capitanes. El daño total de tu ejército es: Daño
¿Qué quieres hacer?
1- Atacar
2.- Retirada
0.- Salir

Has decidido ATACAR
1.- Adelante con todas las unidades
2.- Atacar con una sóla unidad
0.- Salir

¿Con qué unidad quieres atacar?
Has atacado con la unidad X que es un YY y has causado D daño

Has decidido RETIRADA
1.- Retirar todas las unidades
2.- Retirar una sóla unidad
0.- Salir

¿Qué unidad quieres retirar?
Has retirado la unidad XX que ahora causa D de daño

Ejercicio Clases IV

Vamos a modificar la clase Lancero y añadir un método ‘ataqueLanza’ void, sin parámetros y que simplemente nos muestra ‘Ataque con lanza’+danyo.

Una vez hecho esto en nuestro método ‘aLaCarga’ si la unidad es un Lancero, además de llamar a ‘carga’ llamamos a ‘ataqueLanza’

Vamos a modificar ‘aLaCarga’ y si una unidad tiene danyo 0 o menor que no ataque.

Vamos a comprobar en fortaleza y danyo que no puedan tener valores negativos.

Vamos a modificar el constructor de Ejército para que le pasemos el número de soldados, lanceros y capitanes. Haremos una sobrecarga: Si no nos pasan parámetros, como antes. Si nos pasan los parámetros ej: new Ejercito(3,2,1)-> Creará 3 soldados, 2 lanceros y 1 Capitan.

Ejercicio Ejército


package com.trifulcas.ejercitos;

abstract public class Enemigo {
	private String nombre;
	private int fortaleza;
	private int danyo;

	/**
	 * @param nombre the nombre to set
	 */
	protected void setNombre(String nombre) {
		this.nombre = nombre;
	}

	/**
	 * @param fortaleza the fortaleza to set
	 */
	protected void setFortaleza(int fortaleza) {
		this.fortaleza = fortaleza;
	}

	/**
	 * @param danyo the danyo to set
	 */
	protected void setDanyo(int danyo) {
		if (danyo >= 0) {
			this.danyo = danyo;
		}
	}

	/**
	 * @return the nombre
	 */
	public String getNombre() {
		return nombre;
	}

	/**
	 * @return the fortaleza
	 */
	public int getFortaleza() {
		return fortaleza;
	}

	/**
	 * @return the danyo
	 */
	public int getDanyo() {
		return danyo;
	}

	public Enemigo() {
		// TODO Auto-generated constructor stub
	}

}

package com.trifulcas.ejercitos;

abstract public class Infanteria extends Enemigo {
	private int armadura;
	
	
	
	/**
	 * @param armadura the armadura to set
	 */
	protected void setArmadura(int armadura) {
		this.armadura = armadura;
	}

	public Infanteria() {
		// TODO Auto-generated constructor stub
	}
	
	abstract void cargar();
	abstract void retroceder();

}

package com.trifulcas.ejercitos;

abstract public class Caballeria extends Enemigo {
	private int velocidad;

	public Caballeria() {
		// TODO Auto-generated constructor stub
	}

}

package com.trifulcas.ejercitos;

abstract public class Arqueros extends Enemigo {
	private int distancia;

	public Arqueros() {
		// TODO Auto-generated constructor stub
	}

}

package com.trifulcas.ejercitos;

public class Soldado extends Infanteria {

	public Soldado() {
		setNombre("Soldado");
		setFortaleza(50);
		setDanyo(5);
		setArmadura(20);
	}

	@Override
	public void cargar() {
		System.out.println("Ataque de soldados "+getDanyo());
	}

	@Override
	public void retroceder() {
		System.out.println("¡¡Retirada!!!!");
		setFortaleza(getFortaleza()-5);
		setDanyo(getDanyo()-1);
	}

}

package com.trifulcas.ejercitos;

public class Lancero extends Infanteria {

	public Lancero() {
		setNombre("Lancero");
		setFortaleza(60);
		setDanyo(15);
		setArmadura(10);
	}

	@Override
	public void cargar() {
		System.out.println("Ataque de lanceros "+getDanyo());
	}

	@Override
	public void retroceder() {
		System.out.println("¡¡Retirada!!!!");
		setFortaleza(getFortaleza()-4);
		setDanyo(getDanyo()-2);
	}

}

package com.trifulcas.ejercitos;

public class Capitan extends Infanteria {

	public Capitan() {
		setNombre("Capitán");
		setFortaleza(70);
		setDanyo(10);
		setArmadura(40);
	}

	@Override
	public void cargar() {
		System.out.println("Ataque de capitán "+getDanyo());
	}

	@Override
	public void retroceder() {
		System.out.println("¡¡Retirada!!!!");
		setFortaleza(getFortaleza()-5);
		setDanyo(getDanyo()-2);
	}

}

package com.trifulcas.ejercitos;

public class Ejercito {

	Infanteria[] infanteria;
	
	public Ejercito() {
		infanteria=new Infanteria[15];
		for(int i=0;i<10;i++) {
			infanteria[i]=new Soldado();
		}
		for(int i=10;i<14;i++) {
			infanteria[i]=new Lancero();
		}
		infanteria[14]=new Capitan();
	}

}

Ejercicio clases III

Vamos a crear una clase ‘Ejercito’ que, de momento, va a tener como propiedad un array de Infanteria

En el constructor vamos a crear, en ese array, 10 soldados, 4 lanceros y 1 capitan.

Vamos a crear un método totalDanyo que nos devuelva el daño total de todas nuestras unidades.

Vamos a crear un método aLaCarga que activa el método cargar de todas nuestras unidades y nos muestre el daño total

Vamos a crear un método retirada que activa el método retirada de todas nuestras unidades.

Para probarlo en el main creamos un ejército y ejecutamos alguna vez los métodos a ver si hacen lo que tienen que hacer.

Ejercicio Clases II

En la clase Infanteria vamos a poner los siguientes métodos ABSTRACTOS:

void cargar()

void retroceder()

De la clase Infanteria vamos a derivar las siguientes clases que no son abstractas.

Soldado
Tiene un constructor sin parámetros. En el nombre vamos a poner ‘Soldado’ en fortaleza 50, en danyo 5 y en armadura 20.

En el método cargar pondremos un mensaje que ponga ‘Ataque de soldados ‘+ lo que tenga en la popiedad danyo

En el método retroceder que escriba ‘Retirada!!!!’ y que disminuya 5 a la fortaleza y 1 al danyo.

Lancero
Tiene un constructor sin parámetros. En el nombre vamos a poner ‘Lancero’ en fortaleza 60, en danyo 15 y en armadura 10.

En el método cargar pondremos un mensaje que ponga ‘Ataque de lanceros’+ lo que tenga en la popiedad danyo

En el método retroceder que escriba ‘Retirada!!!!’ y que disminuya 4 a la fortaleza y 2 al danyo.

Capitan
Tiene un constructor sin parámetros. En el nombre vamos a poner ‘Capitan’ en fortaleza 70, en danyo 10 y en armadura 40.

En el método cargar pondremos un mensaje que ponga ‘Ataque de soldados ‘+ lo que tenga en la popiedad danyo

En el método retroceder que escriba ‘Retirada!!!!’ y que disminuya 5 a la fortaleza y 2 al danyo.

Ejercicio clases (I)

Vamos a crear unas clases para almacenar información de un juego.

Crearemos la clase ‘Enemigo’ con las siguientes propiedades:

String nombre
int fortaleza
int danyo

Todas privadas y con getters pero no con setters.

De ahí vamos a derivar las siguientes clases: ‘Infanteria’ ‘Caballeria’ ‘Arqueros’

Infanteria tendrá la propiedad:
int armadura
Caballeria tendrá la propiedad:
int velocidad
Arqueros tendrá la propiedad:
int distancia.

Todas las clases son ABSTRACTAS.

Ejemplo abstracción

package com.trifulcas.clases;


abstract public class Repaso {

	private String nombre;
	
	public void saludo() {
		System.out.println("Hola");
	}

	// Método abstracto: contrato de obligación de implementar
	abstract public void despedida();
}

class RepasoExt extends Repaso{
	public void tonteria() {
		System.out.println("Probando");
	}
	public void despedida() {
		System.out.println("Adios");
	}
}
class RepasoExt2 extends Repaso{
	public void otraTonteria() {
		System.out.println("Buuu");
	}

	@Override
	public void despedida() {
		System.out.println("Chao");
		
	}
	
}

Uso:


package com.trifulcas.clases;

public class ProbarClases {

	public static void main(String[] args) {

		RepasoExt r = new RepasoExt();
		RepasoExt2 r2 = new RepasoExt2();

		// Esto da error porque es una clase abstracta
		// Y no se pueden instanciar
		// Repaso r3=new Repaso();

		r.saludo();
		r.tonteria();

		r.despedida();
		r2.saludo();
		r2.otraTonteria();
		r2.despedida();
		System.out.println("----------");
		Repaso[] lista= {new RepasoExt(),new RepasoExt2(),new RepasoExt()};
		for(Repaso el:lista) {
			el.despedida();
		}
	}

}

Ejemplo un poco de todo

package com.trifulcas.clases;

public class Repaso {

	private String nombre;

	// COnstructor se invoca cuando instanciamos la clase
	// Ej. Repaso foo=new Repaso("pepe")
	public Repaso(String nombre) {
		this.nombre = nombre;
	}

	private void saludo() {
		System.out.println("Hola me llamo " + nombre);
	}

	private void despedida() {
		System.out.println("Chao pescao");
	}

	public void holayAdios() {
		saludo();
		despedida();
	}

	/**
	 * @return the nombre
	 */
	public String getNombre() {
		return nombre;
	}

	/**
	 * @param nombre the nombre to set
	 */
	public void setNombre(String nombre) {
		if (nombre.length() >= 4) {
			this.nombre = nombre;
		}
	}

}

class RepasoExtendida extends Repaso {
	private int veces;

	public RepasoExtendida(String nombre) {
		// super llama a la clase madre, en este caso al constructor
		super(nombre);
		veces = 4;
	}

	// Sobreescribo el método holayAdios
	public void holayAdios() {
		for (int i = 0; i < veces; i++) {
			// LLamo a la función holaYAdios de la clase madre
			super.holayAdios();
		}
	}
}

class RepasoExtendida2 extends Repaso {
	private int veces;

	public RepasoExtendida2(String nombre) {
		// super llama a la clase madre, en este caso al constructor
		super(nombre);
		veces = 4;
	}

	// Sobreescribo el método holayAdios
	public void holayAdios() {
		System.out.println("Soy la 2 y digo hola");
	}
}

class RepasoExtendida3 extends Repaso {
	private int veces;

	public RepasoExtendida3(String nombre) {
		// super llama a la clase madre, en este caso al constructor
		super(nombre);
		veces = 4;
	}

	// Sobreescribo el método holayAdios
	public void holayAdios() {
		System.out.println("Hola y adios");
	}
}

Uso:


package com.trifulcas.clases;

public class Repaso {

	private String nombre;

	// COnstructor se invoca cuando instanciamos la clase
	// Ej. Repaso foo=new Repaso("pepe")
	public Repaso(String nombre) {
		this.nombre = nombre;
	}

	private void saludo() {
		System.out.println("Hola me llamo " + nombre);
	}

	private void despedida() {
		System.out.println("Chao pescao");
	}

	public void holayAdios() {
		saludo();
		despedida();
	}

	/**
	 * @return the nombre
	 */
	public String getNombre() {
		return nombre;
	}

	/**
	 * @param nombre the nombre to set
	 */
	public void setNombre(String nombre) {
		if (nombre.length() >= 4) {
			this.nombre = nombre;
		}
	}

}

class RepasoExtendida extends Repaso {
	private int veces;

	public RepasoExtendida(String nombre) {
		// super llama a la clase madre, en este caso al constructor
		super(nombre);
		veces = 4;
	}

	// Sobreescribo el método holayAdios
	public void holayAdios() {
		for (int i = 0; i < veces; i++) {
			// LLamo a la función holaYAdios de la clase madre
			super.holayAdios();
		}
	}
}

class RepasoExtendida2 extends Repaso {
	private int veces;

	public RepasoExtendida2(String nombre) {
		// super llama a la clase madre, en este caso al constructor
		super(nombre);
		veces = 4;
	}

	// Sobreescribo el método holayAdios
	public void holayAdios() {
		System.out.println("Soy la 2 y digo hola");
	}
}

class RepasoExtendida3 extends Repaso {
	private int veces;

	public RepasoExtendida3(String nombre) {
		// super llama a la clase madre, en este caso al constructor
		super(nombre);
		veces = 4;
	}

	// Sobreescribo el método holayAdios
	public void holayAdios() {
		System.out.println("Hola y adios");
	}
}