Una empresa vende productos a varios clientes. Se necesita conocer los datos personales de los clientes (nombre, apellidos, dni, dirección y fecha de nacimiento). Cada producto tiene un nombre y un código, así como un precio unitario. Un cliente puede comprar varios productos a la empresa, y un mismo producto puede ser comprado por varios clientes.
Los productos son suministrados por diferentes proveedores. Se debe tener en cuenta que un producto sólo puede ser suministrado por un proveedor, y que un proveedor puede suministrar diferentes productos. De cada proveedor se desea conocer el NIF, nombre y dirección
Ejemplo ER
Crear un diseño entidad relación que permita controlar el sistema de información de una academia de cursos siguiendo estas premisas:
Se dan clases a alumno. Los datos que se almacenan de los alumnos son el DNI, dirección, nombre, teléfono y la edad
Los cursos que imparte la academia se identifican con un código de curso. Además se almacena el programa del curso, las horas de duración del mismo y el título.
Los cursos los imparte un profesor o profesora (sólo uno por curso) con estos datos son: dni, nombre, apellidos, dirección y teléfono
Se almacena la nota obtenida por cada alumno en cada curso teniendo en cuenta que un mismo alumno o alumna puede realizar varios cursos y en cada cual obtendrá una nota.
Repaso OOP 7: Interfaces
package com.trifulcas.repaso.oop; // Un interface se declara con la palabra clave Interface // En principio se definen métodos sin implementación // Cada clase que implemente este interfaz se compromete // a implementar los métodos definidos en el interface public interface Saludador { public void hola(); public void adios(); }
package com.trifulcas.repaso.oop; // Para implementar un interface uso implements public class AlumnoIntercambio extends Alumno implements Saludador { 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; } // Como implemento el interfaz Saludados tengo que // implementar hola y adios @Override public void hola() { System.out.println("hola"); } @Override public void adios() { System.out.println("adios"); } }
package com.trifulcas.repaso.oop; public class Rectangulo extends Figura implements Saludador, Imprimible{ 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; } // Como implemento el interfaz Saludados tengo que // implementar hola y adios @Override public void hola() { System.out.println("hola, soy un rectángulo"); } @Override public void adios() { System.out.println("Adios pásalo bien"); } @Override public void imprimir() { System.out.println("Imprimir rectángulo"); } }
package com.trifulcas.repaso.oop; import java.util.ArrayList; public class TestOOP { public static void main(String[] args) { // Puedo crear arraylist de interfaces ArrayList<Saludador> saludadores = new ArrayList<>(); saludadores.add(new Rectangulo(2, 3)); saludadores.add(new AlumnoIntercambio("Ana", 3, "www")); saludadores.add(new Rectangulo(8, 5)); // Polimorfismo: como todas las clases implementan Saludador // Yo utilizo los métodos que sé que tendrán que implementar // porque el interfaz es como un contrato for (Saludador saludador : saludadores) { saludador.hola(); saludador.adios(); // Esto no es visible saludador.getArea() // Esto tampoco es visible saludador.getPaisOrigen() } Tigre pepe=new Tigre(); pepe.amamantar(); } }
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()); } } }
Repaso OOP 5: Herencia
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() + "]"; } }
package com.trifulcas.repaso.oop; public class TestOOP { public static void main(String[] args) { AlumnoIntercambio john=new AlumnoIntercambio("John",6,"eee"); // Al derivar de alumno John tiene todas las propiedades // Y métodos que tiene alumno System.out.println(john.getAprobado()); john.setMail("pepe@pee.com"); System.out.println(john); // La subclase puede tener sus propios métodos y propiedades john.setPaisOrigen("Bélgica"); System.out.println(john); Alumno eva=new Alumno("Eva",6,"wwww"); // La superclase no tiene las propiedades de las subclases // Esto da error eva.getPaisOrigen() // Yo puedo definir una variable como la clase madre // Pero instanciarla como la clase hija // Para qué? Polimorfismo Alumno pep=new AlumnoIntercambio("pep",4,"ww"); } }
Repaso OOP 4: static
package com.trifulcas.repaso.oop; // Las clases las definimos con la palabra clave class // Y el nombre de la clase primera en mayúsculas // Recordad que en java el nombre del archivo y la clase debe ser el mismo public 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; // 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 + "]"; } }
package com.trifulcas.repaso.oop; public class Utils { // Si mi clase tiene métodos estáticos public static boolean esPrimo(int numero) { for (int i = 2; i < numero; i++) { if (numero % i == 0) { return false; } } return true; } public static boolean esPar(int numero) { return numero % 2 == 0; } }
package com.trifulcas.repaso.oop; import java.util.Arrays; public class TestOOP { public static void main(String[] args) { Alumno ana=new Alumno("Ana",7,"ana@ana.com"); System.out.println(ana.getNotaCorte()); // Si yo cambio el valor de la nota de corte ana.setNotaCorte(7); Alumno eva = new Alumno("Eva",6); // La cambio para todos los objetos System.out.println(eva.getNotaCorte()); // Puedo acceder sin instanciar el objeto Alumno.setNotaCorte(8); System.out.println(eva.getNotaCorte()); System.out.println(ana.getNotaCorte()); Alumno[] clase=new Alumno[10]; // Creando 10 alumnos for(int i=0;i<10;i++) { clase[i]=new Alumno("Alumno"+i,i); } System.out.println(Arrays.toString(clase)); // Yo puedo usar los métodos estáticos de una clase sin necesidad // de instanciar un objeto de esa clase System.out.println(Utils.esPar(10)); System.out.println(Utils.esPrimo(17)); // Esto no es necesario Utils foo=new Utils(); System.out.println(foo.esPar(8)); } }
Repaso OOP 3: Constructores
package com.trifulcas.repaso.oop; // Las clases las definimos con la palabra clave class // Y el nombre de la clase primera en mayúsculas // Recordad que en java el nombre del archivo y la clase debe ser el mismo public 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; // 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; } }
package com.trifulcas.repaso.oop; public class TestOOP { public static void main(String[] args) { // Como el constructor de Alumno tiene parámetros // Ahora tenemos que pasar los valores que nos piden // Cada vez que hagamos una instancia del objeto Alumno ana=new Alumno("Ana",7,"ana@ana.com"); // Como tengo sobrecargado el constructor puedo llamarlo // solo con dos parámetros Alumno eva = new Alumno("Eva",6); } }
Repaso OOP 2: getters y setters
package com.trifulcas.repaso.oop; // Las clases las definimos con la palabra clave class // Y el nombre de la clase primera en mayúsculas // Recordad que en java el nombre del archivo y la clase debe ser el mismo public 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; private String password; // Si no se pueden modificar desde el exterior no servirían para nada // Las podemos modificar pero desde setters y getters // Son métodos públicos que nos sirven para obtener el valor o // modificarlo pero que son una capa entre mis propiedades // y el exterior // password es una propiedad de solo escritura /** * @param password the password to set */ public void setPassword(String password) { this.password = password; } /** * @return the nombre */ public String getNombre() { return nombre; } /** * @param nombre the nombre to set */ public void setNombre(String nombre) { this.nombre = nombre; } /** * @return the nota */ public int getNota() { return nota; } /** * @param nota the nota to set */ public void setNota(int nota) { // Como yo tengo un setter puedo comprobar los valores // antes de ponerlos if (nota>0 && nota <=10) { this.nota = nota; } } // Mail es de solo lectura /** * @return the mail */ public String getMail() { return mail; } // Esto es una propiedad virtual public boolean getAprobado() { return nota>=5; } }
package com.trifulcas.repaso.oop; public class TestOOP { public static void main(String[] args) { Alumno ana=new Alumno(); // Pongo los valores con set ana.setNombre("Ana"); ana.setNota(8); // Puedo poner password ana.setPassword("1234"); // Obtengo con get System.out.println(ana.getNombre()); // Pero no leerlo // System.out.println(ana.getPassword()); // No puedo poner el mail // ana.setMail("sss"); System.out.println(ana.getMail()); // Yo no sé si esa propiedad existe de verdad o no // Ni me importa: La idea es que de una clase solo conocemos // los métodos que publicamos. Su organización interna // No nos preocupa System.out.println(ana.getAprobado()); } }
Repaso OOP 1
package com.trifulcas.repaso.oop; // Las clases las definimos con la palabra clave class // Y el nombre de la clase primera en mayúsculas // Recordad que en java el nombre del archivo y la clase debe ser el mismo public class Alumno { // Una clase tendrá propiedades, que son variables encapsuladas dentro // de la clase. Las propiedades tienen modificadores // public: todo el mundo puede acceder a la propiedad public String nombre; // protected: solo desde la propia clase, paquete y derivadas protected int nota; // private: solo desde la propia clase private String mail; // Puedo tener métodos // Que tienen los mismos modificadores // Dentro de los métodos de una clase puedo acceder a las // propiedades de la clase public void saludo() { System.out.println("Hola "+nombre+" que tal"); } }
package com.trifulcas.repaso.oop; public class TestOOP { public static void main(String[] args) { // La clase es la 'plantilla' lo que uso son las instancias (objetos) Alumno ana=new Alumno(); // Accedo porque es público ana.nombre="Ana"; // Accedo porque es protected y estoy en el mismo paquete ana.nota=5; // No puedo acceder porque es privada // ana.mail="www"; ana.saludo(); // esta es otra instancia de la clase con sus propios valores // Si yo llamo a saludo utiliza los valores de su instancia Alumno eva=new Alumno(); eva.nombre="Eva"; eva.saludo(); } }
Ejercicio cartas
package com.trifulcas.cartas; public abstract class Carta { private String palo; private int numero; public Carta(String palo, int numero) { this.palo = palo; this.numero = numero; } /** * @return the palo */ public String getPalo() { return palo; } /** * @param palo the palo to set */ public void setPalo(String palo) { this.palo = palo; } /** * @return the numero */ public int getNumero() { return numero; } /** * @param numero the numero to set */ public void setNumero(int numero) { this.numero = numero; } public abstract int getValor(); @Override public String toString() { return numero+" de "+palo; } }
package com.trifulcas.cartas; public class Espanyola extends Carta { public Espanyola(String palo, int numero) { super(palo, numero); } @Override public int getValor() { if (getNumero()>=10) { return 10; } return getNumero(); } }
package com.trifulcas.cartas; public class Francesa extends Carta { public Francesa(String palo, int numero) { super(palo, numero); // TODO Auto-generated constructor stub } @Override public int getValor() { // TODO Auto-generated method stub return getNumero(); } }
package com.trifulcas.cartas; import java.util.ArrayList; import java.util.List; public class Baraja { List<Carta> cartas; public Baraja() { cartas=new ArrayList<>(); } public void addCarta(Carta carta) { cartas.add(carta); } public int totalValor() { int total=0; for(Carta carta:cartas) { total+=carta.getValor(); } return total; } }
package com.trifulcas.cartas; public class TestCartas { public static void main(String[] args) { Carta e=new Francesa("Diamantes",7); System.out.println(e); Carta f=new Espanyola("Bastos",12); System.out.println(f); Baraja b=new Baraja(); b.addCarta(f); b.addCarta(e); System.out.println(b.totalValor()); } }