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());
}
}
}