Clase abstracta e interfaces todo junto
package com.trifulcas.herencia.interfaces;
public abstract class Animal {
private String nombre;
public Animal(String nombre) {
super();
this.nombre = nombre;
}
/**
* @return the nombre
*/
public String getNombre() {
return nombre;
}
/**
* @param nombre the nombre to set
*/
public void setNombre(String nombre) {
this.nombre = nombre;
}
@Override
public String toString() {
return "Animal [nombre=" + nombre + "]";
}
public abstract void hacerRuido();
}
package com.trifulcas.herencia.interfaces;
public class Pato extends Animal implements IVolar, INadar, ICorrer {
public Pato(String nombre) {
super(nombre);
// TODO Auto-generated constructor stub
}
// Lo implemento porque implemento el interfaz IVolar
@Override
public void volar() {
System.out.println("Un patito volando");
}
// Lo implemento porque implemento el interfaz ICorrer
@Override
public void correr() {
System.out.println("Un patito corriendo");
}
// Lo implemento porque implemento el interfaz INadar
@Override
public void nadar() {
System.out.println("Un patito nadando");
}
// Lo tengo que implementar porque lo tiene la clase madre
// Animal
@Override
public void hacerRuido() {
System.out.println("Cua cua");
}
}
package com.trifulcas.herencia.interfaces;
public class Perro extends Animal implements ICorrer, INadar {
public Perro(String nombre) {
super(nombre);
// TODO Auto-generated constructor stub
}
// Lo implemento porque implemento el interfaz ICorrer
@Override
public void correr() {
System.out.println("Un perrito corriendo");
}
// Lo implemento porque implemento el interfaz INadar
@Override
public void nadar() {
System.out.println("Un perrito nadando");
}
// Método abstracto de la clase madre
@Override
public void hacerRuido() {
System.out.println("Guau guau");
}
}
Ejemplos interfaces
package com.trifulcas.herencia.interfaces;
// El interface lo creo con la palabra clave interface
public interface IVolar {
// Dentro del interface defino funciones SIN IMPLEMENTACION
// Igual que los métodos abstractos son una obligación de implementar la función
// Un interface es como un contrato
public void volar();
}
package com.trifulcas.herencia.interfaces;
public interface INadar {
public void nadar();
}
package com.trifulcas.herencia.interfaces;
// En la clase para implementar un interface utilizamos implements
public class Pelicano implements IVolar, INadar{
public Pelicano() {
// TODO Auto-generated constructor stub
}
@Override
public void volar() {
System.out.println("Un majestuoso pelícano surcando el cielo");
}
@Override
public void nadar() {
System.out.println("Un pelícano nadando");
}
}
package com.trifulcas.herencia.interfaces;
public class Murcielago implements IVolar {
public Murcielago() {
// TODO Auto-generated constructor stub
}
@Override
public void volar() {
System.out.println("Un murciélago volando en la noche");
}
}
package com.trifulcas.herencia.interfaces;
public class Avion implements IVolar {
public Avion() {
// TODO Auto-generated constructor stub
}
@Override
public void volar() {
System.out.println("Un avión surcando raudo las nubes");
}
}
package com.trifulcas.herencia.interfaces;
public class Delfin implements INadar {
@Override
public void nadar() {
System.out.println("Un esbelto delfín surcando las procelosas aguas del océano");
}
}
// Lista de elementos que implementan IVolar
ArrayList<IVolar> elementos=new ArrayList<>();
Pelicano p=new Pelicano();
Murcielago m=new Murcielago();
Avion a=new Avion();
// Añadir a la lista cualquier clase que implemente IVolar
elementos.add(a);
elementos.add(p);
elementos.add(m);
// Recorrer la lista con un elemento de tipo IVolar
for(IVolar elemento:elementos) {
elemento.volar();
}
// Lista de elementos que implementan INadar
ArrayList<INadar> nadadores=new ArrayList<>();
Delfin f=new Delfin();
nadadores.add(f);
nadadores.add(p);
// Recorrer la lista con un elemento de tipo INadar
for(INadar elemento:nadadores) {
elemento.nadar();
}
Clases abstractas con métodos abstractos
package com.trifulcas.herencia.abstraccion;
public abstract class FiguraGeometrica {
private int lados;
public FiguraGeometrica(int lados) {
super();
this.lados = lados;
}
/**
* @return the lados
*/
public int getLados() {
return lados;
}
/**
* @param lados the lados to set
*/
public void setLados(int lados) {
this.lados = lados;
}
// En una clase abstracta puedo crear métodos abstractos
// Los métodos abstractos tienen la palabra clave abstract
// Y no tienen implementación: Son como una plantilla
// Obligo a todas las clases derivadas a implementar este método
public abstract double area();
@Override
public String toString() {
return "FiguraGeometrica [lados=" + lados + "]";
}
}
package com.trifulcas.herencia.abstraccion;
public class Cuadrado extends FiguraGeometrica {
private int lado;
public Cuadrado(int lado) {
super(4);
this.lado=lado;
}
@Override
public double area() {
return lado*lado;
}
}
package com.trifulcas.herencia.abstraccion;
public class Triangulo extends FiguraGeometrica {
public Triangulo() {
super(3);
}
@Override
public double area() {
// TODO Auto-generated method stub
return 0;
}
}
// FiguraGeometrica foo=new FiguraGeometrica(3);
Cuadrado c=new Cuadrado(2);
Triangulo t=new Triangulo();
System.out.println(c);
System.out.println(t);
ArrayList<FiguraGeometrica> figuras=new ArrayList<>();
figuras.add(t);
figuras.add(c);
for(FiguraGeometrica f: figuras) {
System.out.println(f.area());
}
Abstracción y polimorfismo
package com.trifulcas.herencia.abstraccion;
public abstract class Empleado {
private String nombre;
// Visible dentro de la propia clase y sus derivadas
protected double sueldo;
private double irpf=.85;
public Empleado(String nombre, double sueldo) {
super();
this.nombre = nombre;
this.sueldo = sueldo;
}
/**
* @return the nombre
*/
public String getNombre() {
return nombre;
}
/**
* @param nombre the nombre to set
*/
public void setNombre(String nombre) {
this.nombre = nombre;
}
/**
* @return the sueldo
*/
public double getSueldo() {
return sueldo;
}
/**
* @param sueldo the sueldo to set
*/
public void setSueldo(double sueldo) {
this.sueldo = sueldo;
}
@Override
public String toString() {
return "Empleado [nombre=" + nombre + ", sueldo=" + sueldo + "]";
}
public double sueldoNeto() {
return sueldo*irpf;
}
}
package com.trifulcas.herencia.abstraccion;
public class Administrativo extends Empleado {
private String departamento;
private int antiguedad=0;
/**
* @return the departamento
*/
public String getDepartamento() {
return departamento;
}
/**
* @param departamento the departamento to set
*/
public void setDepartamento(String departamento) {
this.departamento = departamento;
}
/**
* @return the antiguedad
*/
public int getAntiguedad() {
return antiguedad;
}
/**
* @param antiguedad the antiguedad to set
*/
public void setAntiguedad(int antiguedad) {
this.antiguedad = antiguedad;
}
public Administrativo(String nombre, double sueldo) {
super(nombre, sueldo);
// TODO Auto-generated constructor stub
}
@Override
public double sueldoNeto() {
// Llamo al método de la clase madre que estoy sobreescribiendo
// con la palabra reservada super
return super.sueldoNeto()+antiguedad*100;
}
}
package com.trifulcas.herencia.abstraccion;
public class Comercial extends Empleado {
private double comision;
private double ventas;
public Comercial(String nombre, double sueldo, double comision) {
// Llamo al constructor de la clase madre
super(nombre, sueldo);
// Inicializo las propiedades de mi propia clase
this.comision=comision;
}
/**
* @return the comision
*/
public double getComision() {
return comision;
}
/**
* @param comision the comision to set
*/
public void setComision(double comision) {
this.comision = comision;
}
/**
* @return the ventas
*/
public double getVentas() {
return ventas;
}
/**
* @param ventas the ventas to set
*/
public void setVentas(double ventas) {
this.ventas = ventas;
}
// El sueldo de un comercial es el sueldo menos el irpf
// mas la comisión por las ventas
// SObre escribo el método
@Override
public double sueldoNeto() {
// Llamo al método de la clase madre que estoy sobreescribiendo
// con la palabra reservada super
return super.sueldoNeto()+comision*ventas;
}
}
// La clase Empleado es abstracta, por lo tanto no puedo instanciar
// Da error Empleado emp=new Empleado("foo",3000);
// Pero eso no impide que, en aras del polimorfismo, tengamos variables
// (e incluso listas) de tipo empleado
ArrayList<Empleado> empresa=new ArrayList<>();
// Estas variables se pueden instanciar porque sus clases no son abstractas
Comercial ana=new Comercial("Ana",2000,.02);
Administrativo eva=new Administrativo("Eva",2000);
Comercial pep=new Comercial("Pepe",1000,.04);
// Y las podemos añadir a una lista de empleados porque derivan de ella
// (Igual que lo podíamos hacer antes)
// Esto no es problemático, porque no instanciamos Empleado, sino las clases derivadas
empresa.add(pep);
empresa.add(eva);
empresa.add(ana);
// Podemos recorrer la lista con una variable 'empleado'
for(Empleado emp:empresa) {
System.out.println(emp.getSueldo());
}
Solución 2.0
package com.trifulcas.herencia;
public class Vehiculo {
private int velocidad;
private int direccion;
protected int velocidadMaxima;
protected int aceleracion;
protected int giro;
public Vehiculo() {
velocidadMaxima = 200;
aceleracion=10;
giro=10;
}
public void acelerar() {
velocidad += aceleracion;
if (velocidad > velocidadMaxima) {
velocidad = velocidadMaxima;
}
}
public void frenar() {
velocidad -= aceleracion;
if (velocidad < 0) {
velocidad = 0;
}
}
public void izquierda() {
direccion += giro;
if (direccion >= 360) {
direccion -= 360;
}
}
public void derecha() {
direccion -= giro;
if (direccion < 0) {
direccion += 360;
}
}
@Override
public String toString() {
return "Vehiculo [velocidad=" + velocidad + ", direccion=" + direccion + "]";
}
}
package com.trifulcas.herencia;
public class Coche extends Vehiculo {
public Coche() {
velocidadMaxima=150;
}
}
package com.trifulcas.herencia;
public class Bicicleta extends Vehiculo {
public Bicicleta() {
aceleracion=3;
}
}
package com.trifulcas.herencia;
public class Tanque extends Vehiculo {
public Tanque() {
giro=90;
}
}
Soluciones ejercicios
package com.trifulcas.herencia;
public class Producto {
protected String nombre;
protected String familia;
public Producto(String nombre, String familia) {
super();
this.nombre = nombre;
this.familia = familia;
}
/**
* @return the nombre
*/
public String getNombre() {
return nombre;
}
/**
* @param nombre the nombre to set
*/
public void setNombre(String nombre) {
this.nombre = nombre;
}
/**
* @return the familia
*/
public String getFamilia() {
return familia;
}
/**
* @param familia the familia to set
*/
public void setFamilia(String familia) {
this.familia = familia;
}
@Override
public String toString() {
return "Producto [nombre=" + nombre + ", familia=" + familia + "]";
}
}
package com.trifulcas.herencia;
public class Asiento extends Producto {
protected int numeroPatas;
public Asiento(String nombre, String familia, int numeroPatas) {
super(nombre, familia);
this.numeroPatas=numeroPatas;
}
}
package com.trifulcas.herencia;
public class Silla extends Asiento{
public Silla(String nombre, String familia, int numeroPatas) {
super(nombre, familia, numeroPatas);
}
}
package com.trifulcas.herencia;
public class Sillon extends Asiento {
public Sillon(String nombre, String familia, int numeroPatas) {
super(nombre, familia, numeroPatas);
}
}
package com.trifulcas.herencia;
public class Vehiculo {
protected int velocidad;
protected int direccion;
public void acelerar() {
velocidad+=10;
if (velocidad>200) {
velocidad=200;
}
}
public void frenar() {
velocidad-=10;
if (velocidad<0) {
velocidad=0;
}
}
public void izquierda() {
direccion+=10;
if (direccion>=360) {
direccion-=360;
}
}
public void derecha() {
direccion-=10;
if (direccion<0) {
direccion+=360;
}
}
@Override
public String toString() {
return "Vehiculo [velocidad=" + velocidad + ", direccion=" + direccion + "]";
}
}
package com.trifulcas.herencia;
public class Coche extends Vehiculo {
public void acelerar() {
velocidad+=10;
if (velocidad>150) {
velocidad=150;
}
}
}
package com.trifulcas.herencia;
public class Bicicleta extends Vehiculo {
public void acelerar() {
velocidad+=3;
if (velocidad>200) {
velocidad=200;
}
}
public void frenar() {
velocidad-=3;
if (velocidad<0) {
velocidad=0;
}
}
}
package com.trifulcas.herencia;
public class Tanque extends Vehiculo {
public void izquierda() {
direccion+=90;
if (direccion>=360) {
direccion-=360;
}
}
public void derecha() {
direccion-=90;
if (direccion<0) {
direccion+=360;
}
}
}
Empleados v 2.0
package com.trifulcas.herencia;
public class Empleado {
private String nombre;
// Visible dentro de la propia clase y sus derivadas
protected double sueldo;
private double irpf=.85;
public Empleado(String nombre, double sueldo) {
super();
this.nombre = nombre;
this.sueldo = sueldo;
}
/**
* @return the nombre
*/
public String getNombre() {
return nombre;
}
/**
* @param nombre the nombre to set
*/
public void setNombre(String nombre) {
this.nombre = nombre;
}
/**
* @return the sueldo
*/
public double getSueldo() {
return sueldo;
}
/**
* @param sueldo the sueldo to set
*/
public void setSueldo(double sueldo) {
this.sueldo = sueldo;
}
@Override
public String toString() {
return "Empleado [nombre=" + nombre + ", sueldo=" + sueldo + "]";
}
public double sueldoNeto() {
return sueldo*irpf;
}
}
package com.trifulcas.herencia;
public class Comercial extends Empleado {
private double comision;
private double ventas;
public Comercial(String nombre, double sueldo, double comision) {
// Llamo al constructor de la clase madre
super(nombre, sueldo);
// Inicializo las propiedades de mi propia clase
this.comision=comision;
}
/**
* @return the comision
*/
public double getComision() {
return comision;
}
/**
* @param comision the comision to set
*/
public void setComision(double comision) {
this.comision = comision;
}
/**
* @return the ventas
*/
public double getVentas() {
return ventas;
}
/**
* @param ventas the ventas to set
*/
public void setVentas(double ventas) {
this.ventas = ventas;
}
// El sueldo de un comercial es el sueldo menos el irpf
// mas la comisión por las ventas
// SObre escribo el método
@Override
public double sueldoNeto() {
// Llamo al método de la clase madre que estoy sobreescribiendo
// con la palabra reservada super
return super.sueldoNeto()+comision*ventas;
}
}
package com.trifulcas.herencia;
public class Administrativo extends Empleado {
private String departamento;
private int antiguedad=0;
/**
* @return the departamento
*/
public String getDepartamento() {
return departamento;
}
/**
* @param departamento the departamento to set
*/
public void setDepartamento(String departamento) {
this.departamento = departamento;
}
/**
* @return the antiguedad
*/
public int getAntiguedad() {
return antiguedad;
}
/**
* @param antiguedad the antiguedad to set
*/
public void setAntiguedad(int antiguedad) {
this.antiguedad = antiguedad;
}
public Administrativo(String nombre, double sueldo) {
super(nombre, sueldo);
// TODO Auto-generated constructor stub
}
@Override
public double sueldoNeto() {
// Llamo al método de la clase madre que estoy sobreescribiendo
// con la palabra reservada super
return super.sueldoNeto()+antiguedad*100;
}
}
Empleado ana = new Empleado("Ana", 3000);
System.out.println(ana);
System.out.println(ana.sueldoNeto());
Comercial eva = new Comercial("Eva", 2500, 0.05);
eva.setComision(0.05);
eva.setVentas(10000);
System.out.println(eva);
System.out.println(eva.sueldoNeto());
Administrativo pepe=new Administrativo("Pepe",2000);
pepe.setAntiguedad(20);
System.out.println(pepe.sueldoNeto());
// Estoy creando una lista de empleados
ArrayList<Empleado> empresa=new ArrayList<>();
// Añado ana porque es empleado
empresa.add(ana);
// Puedo añadir eva porque deriva de empleado
empresa.add(eva);
// Puedo añadir a pepe por la misma razón
empresa.add(pepe);
// Polimorfismo
// Polimorfismo es utilizar métodos comunes en clases derivadas
// Aunque tengan comportamientos diferentes
// Yo puedo hacer lo siguiente:
for(Empleado emp:empresa) {
System.out.println(emp.getNombre() + " - " + emp.sueldoNeto());
}
Sobreescritura
package com.trifulcas.herencia;
public class Empleado {
private String nombre;
private double sueldo;
/**
* @return the nombre
*/
public String getNombre() {
return nombre;
}
/**
* @param nombre the nombre to set
*/
public void setNombre(String nombre) {
this.nombre = nombre;
}
/**
* @return the sueldo
*/
public double getSueldo() {
return sueldo;
}
/**
* @param sueldo the sueldo to set
*/
public void setSueldo(double sueldo) {
this.sueldo = sueldo;
}
@Override
public String toString() {
return "Empleado [nombre=" + nombre + ", sueldo=" + sueldo + "]";
}
public double sueldoNeto() {
return sueldo*.85;
}
}
package com.trifulcas.herencia;
public class Comercial extends Empleado {
private double comision;
private double ventas;
/**
* @return the comision
*/
public double getComision() {
return comision;
}
/**
* @param comision the comision to set
*/
public void setComision(double comision) {
this.comision = comision;
}
/**
* @return the ventas
*/
public double getVentas() {
return ventas;
}
/**
* @param ventas the ventas to set
*/
public void setVentas(double ventas) {
this.ventas = ventas;
}
// El sueldo de un comercial es el sueldo menos el irpf
// mas la comisión por las ventas
// SObre escribo el método de la clase madre
@Override
public double sueldoNeto() {
return getSueldo()*.85+comision*ventas;
}
}
Empleado ana=new Empleado();
ana.setNombre("Ana");
ana.setSueldo(3000);
System.out.println(ana);
System.out.println(ana.sueldoNeto());
Comercial eva=new Comercial();
eva.setNombre("Eva");
eva.setSueldo(2500);
eva.setComision(0.05);
eva.setVentas(10000);
System.out.println(eva);
System.out.println(eva.sueldoNeto());
Herencia primera parte: Un ejemplo
En java las clases pueden tener clases derivadas o dicho de otra manera una clase puede extender a otra.
La clase derivada o hija HEREDA todas las propiedades de la clase madre.
package com.trifulcas.herencia;
public class Animal {
private String nombre;
private int patas;
/**
* @return the nombre
*/
public String getNombre() {
return nombre;
}
/**
* @param nombre the nombre to set
*/
public void setNombre(String nombre) {
this.nombre = nombre;
}
/**
* @return the patas
*/
public int getPatas() {
return patas;
}
/**
* @param patas the patas to set
*/
public void setPatas(int patas) {
this.patas = patas;
}
public void hacerRuido() {
System.out.println("Grrr");
}
}
package com.trifulcas.herencia;
public class Mamifero extends Animal {
private int mesesLactancia;
/**
* @return the mesesLactancia
*/
public int getMesesLactancia() {
return mesesLactancia;
}
/**
* @param mesesLactancia the mesesLactancia to set
*/
public void setMesesLactancia(int mesesLactancia) {
this.mesesLactancia = mesesLactancia;
}
}
package com.trifulcas.herencia;
public class Insecto extends Animal {
}
package com.trifulcas.herencia;
public class Perro extends Mamifero {
private String raza;
/**
* @return the raza
*/
public String getRaza() {
return raza;
}
/**
* @param raza the raza to set
*/
public void setRaza(String raza) {
this.raza = raza;
}
}
Animal prueba=new Animal();
prueba.setNombre("Bicho");
prueba.setPatas(18);
// Mamifero extiende la clase animal
// Y por lo tanto HEREDA todas sus propiedades y métodos
Perro michucho=new Perro();
// toString lo hereda de Object
System.out.println(michucho.toString());
// setNombre lo hereda de animal
michucho.setNombre("firulai");
// setMeseslactancia de mamifero
michucho.setMesesLactancia(8);
// setRaza de Perro
michucho.setRaza("Bulldog");
/*
* ANIMAL
*
* MAMIfERO
*
* PERRO Hereda todas las propiedades de mamifero y animal
*
*/