Refactorización de Vehiculo

Con esta refactorización haced lo mismo para frenar y girar.


package com.trifulcas.clases;

public class Vehiculo {

protected int velocidad;
protected int direccion;
protected int velocidadMaxima;

public Vehiculo() {
velocidadMaxima=200;
}

// El método acelerar con cuaalquier valor solo es accesible
// A la propia clase y sus derivadas. No es accesible al usuario
protected void acelerar(int cantidad) {
velocidad+=cantidad;
if (velocidad>velocidadMaxima) {
velocidad=velocidadMaxima;
}
}

public void acelerar() {
acelerar(10);
}
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;
}
}
public String estado() {
return velocidad+" | "+direccion+" | "+velocidadMaxima;
}
}

class Coche extends Vehiculo{
public Coche() {
velocidadMaxima=150;
}
}

class Bicicleta extends Vehiculo{
public void acelerar() {
acelerar(3);
}
public void frenar() {
velocidad-=3;
if (velocidad<0) {
velocidad=0;
}
}
}
class Tanque extends Vehiculo{
public void izquierda() {
direccion+=90;
if (direccion>=360) {
direccion-=360;
}
}
public void derecha() {
direccion-=90;
if (direccion<0) {
direccion+=360;
}
}
}

Resultado:


package com.trifulcas.clases;

public class Vehiculo {

	protected int velocidad;
	protected int direccion;
	protected int velocidadMaxima;
	protected int velocidadMinima;
	protected int giroMax;
	protected int giroMin;
	
	public Vehiculo() {
		velocidadMaxima=200;
		velocidadMinima=0;
		giroMax=360;
		giroMin=0;
	}
	
	// El método acelerar con cualquier valor solo es accesible
	// A la propia clase y sus derivadas. No es accesible al usuario
	protected void cambiar(int cantidad) {
		velocidad+=cantidad;
		if (velocidad>velocidadMaxima) {
			velocidad=velocidadMaxima;
		}
		if(velocidad<velocidadMinima) {
			velocidad=velocidadMinima;
		}
	}
	/**
	 * Acelera el coche 10 unidades
	 * La velocidad máxima es de 200 km/hora
	 */
	public void acelerar() {
		cambiar(10);
	}
	/** 
	 * Frena el coche 10 unidades
	 */
	public void frenar() {
		cambiar(-10);
	}
	protected void girar(int cantidad) {
		direccion+=cantidad;
		if (direccion>giroMax) {
			direccion-=giroMax;
		}
		if (direccion<giroMax) {
			direccion+=giroMax;
		}
	}
	public void izquierda() {
		girar(10);
	}
	public void derecha() {
		girar(-10);
	}
	public String estado() {
		return velocidad+" | "+direccion+" | "+velocidadMaxima;
	}
}

class Coche extends Vehiculo{
	public Coche() {
		velocidadMaxima=150;
	}
}

class Bicicleta extends Vehiculo{
	public void acelerar() {
		cambiar(3);
	}
	public void frenar() {
		cambiar(-3);
	}
}
class Tanque extends Vehiculo{
	public void izquierda() {
		girar(90);
	}
	public void derecha() {
		girar(-90);
	}
}

Ejercicio Herencia

Vamos a crear una clase ‘Vehiculo’ con las siguientes propiedades:

velocidad, direccion de tipo entero

Tendrá los siguientes métodos:

acelerar(): Incrementa 10 a la velocidad
frenar(): decrementa 10 a la velocidad
izquierda(): Suma 10 a la dirección
derecha(): Resta 10 a la dirección.

Si la velocidad es 0 no podemos frenar más.
Si la velocidad es mayor de 200 no podemos acelerar más.

Si la dirección es mayor o igual de 360 le restamos 360.
Si la dirección es negativa le sumamos 360.
Ejemplos: direccion: 350 y ejecutamos izquierda. Debería valer 360, pero le restamos 360 y pasa a valer 0.
direccion vale 0 y ejecutamos derecha. Debería valer -10, pero le sumamos 360 y pasa a valer 350.

De aquí vamos a derivar las siguientes clases:

Coche
La velocidad máxima es de 150. ¿QUé tendríamos que hacer para conseguirlo?
Bicicleta
Acelerar y frenar incrementan la velocidad en 3 en vez de 10
Tanque
Al girar a la izquierda o a la derecha se giran 90 en vez de 10.

package com.trifulcas.clases;

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;
		}
	}
	public String estado() {
		return velocidad+" | "+direccion;
	}
}

class Coche extends Vehiculo{
	public void acelerar() {
		velocidad+=10;
		if (velocidad>150) {
			velocidad=150;
		}
	}
}

class Bicicleta extends Vehiculo{
	public void acelerar() {
		velocidad+=3;
		if (velocidad>200) {
			velocidad=200;
		}
	}
	public void frenar() {
		velocidad-=3;
		if (velocidad<0) {
			velocidad=0;
		}
	}
}
class Tanque extends Vehiculo{
	public void izquierda() {
		direccion+=90;
		if (direccion>=360) {
			direccion-=360;
		}
	}
	public void derecha() {
		direccion-=90;
		if (direccion<0) {
			direccion+=360;
		}
	}
}

Uso:

package com.trifulcas.clases;


public class ProbarClases {

	public static void main(String[] args) {
	
		Coche foo=new Coche();
		Bicicleta bike=new Bicicleta();
		Tanque panzer=new Tanque();
		
		System.out.println(panzer.estado());
		panzer.izquierda();
		System.out.println(panzer.estado());
		
		for(int i=0;i<20;i++) {
			foo.acelerar();
			bike.acelerar();
		}
		System.out.println(foo.estado());
		foo.frenar();
		foo.frenar();
		foo.frenar();
		System.out.println(foo.estado());
		foo.derecha();
		foo.derecha();
		System.out.println(foo.estado());
	}
	public static double PVP(double precio) {
		return precio*1.21;
	}

}

Ejemplo Herencia

package com.trifulcas.clases;

//Herencia
class Producto {
public String nombre;
public double precio;
}

class Intangible extends Producto {
public String url;
}

class Tangible extends Producto {
public int stock;
}

class Reposteria extends Tangible {
public String caracteristicas;
}

//Agregación
class Almacen {
public Reposteria pasteles;
public Reposteria magdalenas;
public Intangible cupon;

}
[/Java]

Ejemplos modificadores públicos y privados

package com.trifulcas.clases;

public class Profesor {

	private String name;
	private String email;
	private double sueldo;
	private double dietas;
	private String password;
	private String direccion;
	
	// getters y setters: Poner y obtener valores
	// Getter: obtiene el valor
	public String getNombre() {
		return name;
	}
	//Setter: pone el valor
	public void setNombre(String nombre) {
		this.name=nombre;
	}
	public String getEmail() {
		return email;
	}
	public void setEmail(String valor) {
		email = valor;
	}
	/**
	 * 
	 * @return
	 */
	public double getSueldo() {
		return sueldo+dietas;
	}
	/**
	 * 
	 * @param sueldo
	 */
	public void setSueldo(double sueldo) {
		this.sueldo = sueldo*.9;
		this.dietas= sueldo*.1;
	}
	// Como password sólo tiene un setter y no tiene getter
	// Es una propiedad de solo escritura. Podemos poner un valor
	// Pero no recuperarlo
	public void setPassword(String password) {
		this.password=password;
	}
	
	// Como dietas sólo tiene getter podemos obtener el valor
	// Pero no podemos modificarlo. Es una propiedad de sólo lectura
	public double getDietas() {
		return dietas;
	}
	/**
	 * @return la dirección del profesor
	 */
	public String getDireccion() {
		return direccion;
	}
	/**
	 * Esta función es un setter
	 * @param direccion Es la dirección del profesor (calle y número)
	 */
	public void setDireccion(String direccion) {
		this.direccion = direccion;
	}
	
	
}

public static void main(String[] args) {
		Profesor juan=new Profesor();
		
		juan.setNombre("Juan");
		juan.setSueldo(1000);
		juan.setPassword("12345");
		System.out.println(juan.getNombre());
		System.out.println(juan.getSueldo());
		System.out.println(juan.getDietas());
		
	}

Ejercicios de clases

Vamos a crear una clase ’empleado’ con las siguientes propiedades:
nombre de tipo String y sueldo de tipo double
Vamos a añadir una función sueldoNeto que nos devuelve:
1.- El sueldo multiplicado por 0.9 si el sueldo es menor de 2000
1.- El sueldo multiplicado por 0.85 si el sueldo es mayor o igual que 2000.

Vamos a crear una clase ‘cesta’ con las siguientes propiedades:

Cliente de tipo String, importe de tipo double, cantidad de tipo int.

Crearemos también las funciones total que nos devuelve el importe por la cantidad
Y totalConIva que nos devuelve el importe con la cantidad multiplicado por 21%

A esta clase le añadimos una propiedad IVA de tipo double y un constructor.
El constructor nos pide el nombre del cliente como parámetro y nos pone .21 en el IVA

Vamos a crear la clase Alumno. Tiene de propiedades:
Nombre, nota, curso y actitud
nota es de tipo double, curso de tipo String, actitud de tipo int.
En el constructor pedimos el nombre y ponemos actitud=5
Creamos una función puntuar a la que le pasamos un valor y nos lo guarda en nota.
Tenemos una función castigo que resta 1 a la actitud
Tenemos una función recompensa que suma 1 a la actitud
Tenemos una función aprobado que nos devuelve un booleano que es true si la nota y la actitud son mayores o iguales a 5.


public class Alumno {

	public String nombre;
	public double nota;
	public String curso;
	public int actitud;

	public Alumno(String nombre) {
		this.nombre = nombre;
		actitud = 5;
	}

	public void puntuar(double nota) {
		this.nota = nota;
	}

	public void castigo() {
		actitud--;
	}

	public void recompensa() {
		actitud++;
	}

	public boolean aprobado() {
		return nota >= 5 && actitud >= 5;
	}
}

public static void main(String[] args) {
		Alumno eva=new Alumno("Eva García");
		
		eva.puntuar(8);
		eva.recompensa();
		System.out.println(eva.nota);
		System.out.println(eva.actitud);
		System.out.println(eva.aprobado());
		
		
	}

Resumen OOP

OOP

La programación orientada a objetos se basa en definir clases
que después se instancian en objetos
La clase es la definición de las propiedades y métodos
que tendrá un objeto. Pero no es un objeto.
El objeto es la instancia de la clase y es con lo que se
trabaja.

Ejemplo: Clase: fruta Objeto: Pera
Clase: Plano de una casa Objeto: La casa

Yo no puedo vivir en el plano de una casa pero la casa
no se puede construir si no tenemos un plano.

Para definir una clase usamos la palabra reservada ‘class’

public class MiClase{

}

Buena práctica: Las clases empiezan con mayúsculas

Para instanciar un objeto usamos la palabra reservada ‘new’

MiClase miobjeto=new MiClase()

¿Qué puede tener una clase?
Propiedades y funciones
Las propiedades son valores de mi clase y las funciones procedimientos que tengo ahí para calcular cosas
Que pueden utilizar los valores de la clase. Para ello usamos la palabra reservada ‘this’

public class Alumno{
public String nombre;
public void saludo(){
System.out.println(“Hola me llamo “+this.nombre);
}
}

Las clases tienen también un constructor que se lo que primero se ejecuta cuando instanciamos la clase.
El constructor no tiene una indicación de parámetro a devolver y se llama igual que la clase.

public class Alumno{
public String nombre;
public void saludo(){
System.out.println(“Hola me llamo “+this.nombre);
}
public Alumno(){
}
}

Los constructores pueden tener parámetros en cuyo caso al instanciarlos debemos indicarlos.

public class Alumno{
public String nombre;
public void saludo(){
System.out.println(“Hola me llamo “+this.nombre);
}
public Alumno(String nombre){
this.nombre=nombre;
}
}

Alumno Ana=new Alumno(“Ana Pi”);

https://www.javatpoint.com/java-oops-concepts

https://asociacionaepi.es/programacion-orientada-a-objetos-en-java/

Ejemplo clase y constructores

package com.trifulcas.clases;

public class Producto {
	public String referencia;
	public double precio;
	public double iva;
	public double descuento;
	
	
	public double PVP() {
		// La palabra clave this hace referencia al valor
		// de la propiedad del objeto en el que estamos
		return this.precio*(1+this.iva);
	}
	// Función descuento que nos devuelva el precio menos un 10%
	public double descuento() {
		return this.PVP()*(1-this.descuento);
	}
	// Toda clase puede tener un constructor
	// Se llama cuando instanciamos la clase, al hacer new
	// Si pongo un parámetro en elconstructor
	// Obligo a que cuando se instancie pongan ese valor
	public Producto(String referencia) {
		// ¿Qué ponemos dentro de un constructor?
		// Todas aquellas inicializaciones que necesite nuestra clase
		// Si nuestra clase necesita algunos valores por defecto
		// También los ponemos aquí
		this.referencia=referencia;
		this.iva=.21;
		this.descuento=.1;
	}
	
}

package com.trifulcas.clases;

public class ProbarClases {

	public static void main(String[] args) {
		// Al tener un constructor con parámetro
		// Se lo tengo que pasar al instanciarlo
		Producto tarta=new Producto("Tarta chupiguay");
		Producto cupcake=new Producto("Magdalena con ínfulas");

		// Esto ahora da error porque es obligatorio pasar la referencia
		//Producto foo=new Producto();
		
		tarta.precio=100;
		
		cupcake.precio=10;
		
		System.out.println(tarta.referencia);
		System.out.println(tarta.PVP());
		System.out.println(tarta.descuento());
		System.out.println(PVP(tarta.precio));
		System.out.println(cupcake.PVP());
		
	}
	public static double PVP(double precio) {
		return precio*1.21;
	}

}

Ejemplos de clases

package com.trifulcas.saludo;

public class EjemplosClases {

	public static void main(String[] args) {
		// Para instanciar una clase creo una variable de ese tipo
		// Y con la palabra clave new INSTANCIO la clase
		Alumno ana=new Alumno();
		
		ana.nombre="Ana Pi";
		
		Alumno pep=new Alumno();
		
		pep.nombre="Pepe Bou";
		
		Alumno[] alumnos=new Alumno[4];
		alumnos[0]=new Alumno();
		alumnos[0].nombre="Eva";
		
		for(int i=0;i<4;i++) {
			alumnos[i]=new Alumno();
			alumnos[i].nombre="Alumno "+i;
		}
		// Esto no lo puedo hacer porque Alumno es una CLASE
		// Es decir, una definición, no un objeto
		// Alumno.nombre="Juan";

		Empleado eva=new Empleado();
		eva.nombre="Eva Pou";
	}
	
	// Definiendo las propiedades y funciones de la clase Alumno
	public static class Alumno{
		public String nombre;
	}

}

package com.trifulcas.saludo;

public class Empleado {
	public String nombre;
}

Recursividad

package com.trifulcas.saludo;

public class Recursividad {
	public static void main(String[] args) {
		System.out.println(factorial(5));
		System.out.println(fibonacci(5));
		System.out.println(fibonacci(8));
	}

	// Una función recursiva es una función que se llama a sí misma
	// Factorial: multiplicación desde el 1 hasta el número
	// Factorial: N! -> N*(N-1)! 1!->1
	// factorial(5)-->5*factorial(4)
	// factorial(4)-->4*factorial(3)
	// factorial(3)-->3*factorial(2)
	// factorial(2)-->2*factorial(1)
	// factorial(1)-->1
	public static int factorial(int num) {
		if (num <= 1) {
			return 1;
		} else {
			return num * factorial(num - 1);
		}
	}
	
	/*
	 * Las reglas para definir una función recursiva son dos
	 * a) Tener un caso base, es decir habrá un momento en el que la función
	 * devuelve un valor fijo.
	 * b) Descomponer el problema en la misma función pero de valores más pequeños
	 */
	
	/*
	 * Sucesión de fibonacci. Empezamos con 1,1 y cada número es la suma de los dos anteriores
	 * 1,1,2,3,5,8,13,21,34,....
	 * Obtener el elemento N de la sucesión de fibonacci
	 * Si N es 1 o 2 --> 1
	 * El elemento N es igual a suma de fib(N-1) + fib(N-2)
	 */
	public static int fibonacci(int posicion) {
		if(posicion<=2) {
			return 1;
		} else {
			return fibonacci(posicion-1)+fibonacci(posicion-2);
		}
	}
}