package com.trifulcas.repaso.oop; // Una clase abstracta es igual que una clase con la diferencia // de que no se puede instanciar un objeto de ella public abstract class Alumno { // Lo habitual es que todas las propiedades sean private // Para evitar que se puedan modificar desde el exterior private String nombre; private int nota; private String mail; // En una clase abstracta puedo tener métodos abstractos // Son métodos con 'firma' (parámetros y tipo de retorno) // Pero sin implementación // Un método abastracto solo puede estar en una clase abstracta public abstract int media(); // Las propiedades o métodos estáticos solo existen una vez // (es decir, hay una única instancia para todos los objetos de esta clase) // Podemos acceder a ellos sin instanciar un objeto // La información es compartida por todos private static int notaCorte=5; // El constructor es la manera como se construye la instancia // de la clase. Es el punto de entrada // Podemos tener parámetros o no y podemos tener sobrecargas // Un ejemplo típico sería este. Usamos todas las propiedades public Alumno(String nombre, int nota, String email) { // La palabra clave this hace referencia al propio objeto // La usamos para desambiguar entre el nombre de los parámetros // y de las propiedades de la clase this.nombre = nombre; this.nota = nota; // Aquí no hace falta desambiguar porque se llaman diferente mail = email; } // Yo los constructores los puedo sobrecargar public Alumno(String nombre, int nota) { this.nombre = nombre; this.nota = nota; mail = "No tiene"; // this(nombre,nota,"No tiene") } // Si yo hago sobrecarga lo suyo es que llamemos al otro constructor public Alumno(String nombre) { /* Si yo quiero hacer esto this.nombre = nombre; this.nota = 0; mail = "No tiene"; Lo mejor es hacer esto: */ this(nombre,0,"No tiene"); // this hace referencia al constructor } public String getNombre() { return nombre; } public void setNombre(String nombre) { this.nombre = nombre; } public int getNota() { return nota; } public void setNota(int nota) { this.nota = nota; } public String getMail() { return mail; } public void setMail(String mail) { this.mail = mail; } public boolean getAprobado() { // La nota de corte es la misma para todos los objetos return nota>=notaCorte; } public static int getNotaCorte() { return notaCorte; } public static void setNotaCorte(int notaCorte) { Alumno.notaCorte = notaCorte; } @Override public String toString() { return "Alumno [nombre=" + nombre + ", nota=" + nota + ", mail=" + mail + "]"; } public static void aprobar(Alumno al) { al.setNota(10); } }
package com.trifulcas.repaso.oop; // La herencia se implementa con extends // AlumnoIntercambio deriva de Alumno // Alumno es la superclase o clase madre // y AlumnoIntercambio la clase hija o derivada o subclase public class AlumnoIntercambio extends Alumno { private String paisOrigen; public String getPaisOrigen() { return paisOrigen; } public void setPaisOrigen(String paisOrigen) { this.paisOrigen = paisOrigen; } public AlumnoIntercambio(String nombre, int nota, String email) { super(nombre, nota, email); } public void saludo() { // Recordad que las propiedades private no son visibles desde // la clase derivada, esto da error // System.out.println("hola "+nombre); System.out.println("hola "+getNombre()); } // Sobreescribir los métodos que heredo de la clase madre // Y tener otra implementación, en este caso el toString @Override public String toString() { // La palabra clave super hace referencia a la clase madre // Aquí lo usamos para acceder al método toString de Alumno return "AlumnoIntercambio [paisOrigen=" + paisOrigen + ", " + super.toString() + "]"; } // Si clase madre tiene un método abstracto en la clase derivada // Estamos obligados a implementarlo @Override public int media() { return 0; } // En una clase que no es abstracta no puedo tener un método abstracto // Error: public abstract int foo(); }
package com.trifulcas.repaso.oop; public abstract class Figura { public abstract double getArea(); public abstract double getPerimetro(); }
package com.trifulcas.repaso.oop; public class Cuadrado extends Figura{ private double lado; public Cuadrado(int lado) { super(); this.lado = lado; } public double getLado() { return lado; } public void setLado(double lado) { this.lado = lado; } @Override public double getArea() { // TODO Auto-generated method stub return lado*lado; } @Override public double getPerimetro() { // TODO Auto-generated method stub return lado*4; } }
package com.trifulcas.repaso.oop; public class Rectangulo extends Figura{ private double base; private double altura; public Rectangulo(double base, double altura) { super(); this.base = base; this.altura = altura; } public double getBase() { return base; } public void setBase(double base) { this.base = base; } public double getAltura() { return altura; } public void setAltura(double altura) { this.altura = altura; } @Override public double getArea() { // TODO Auto-generated method stub return base*altura; } @Override public double getPerimetro() { // TODO Auto-generated method stub return base+2+altura*2; } }
package com.trifulcas.repaso.oop; import java.util.ArrayList; public class TestOOP { public static void main(String[] args) { // Esto ahora da error porque al ser abstracta Alumno // No podemos crear una instancia // Alumno eva=new Alumno("Eva",6,"wwww"); // No puedo hacer Figura foo=new Figura() ArrayList<Figura> figuras=new ArrayList<>(); figuras.add(new Cuadrado(5)); figuras.add(new Rectangulo(2,3)); figuras.add(new Cuadrado(7)); figuras.add(new Rectangulo(12,4)); // Polimorfismo: como todas las clases derivan de figura // Yo utilizo los métodos que sé que tendrán por derivar // de 'Figura', aunque cada clase tiene su propia implementación for(Figura figura:figuras) { System.out.println(figura.getArea()); } } }