Repaso OOP 6: Abstracción

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

}

Publicado por

Juan Pablo Fuentes

Formador de programación y bases de datos