Herència: Geometria.java // fichero Geometria.java public abstract class Geometria { // clase abstracta que no puede tener objetos public abstract double area(); public abstract double perimetro(); } 1 Herència: Circulo.java // fichero Circulo.java public class Circulo extends Geometria { static int numCirculos=0; public static final double PI=3.14159265358979323846; public double x, y, r; public Circulo(double xx, double yy, double rr) { x=xx; y=yy; r=rr; numCirculos++; } public Circulo(double rr) { x=0.0; y=0.0; r=rr; numCirculos++; } public double area() { return PI * r * r; } public double perimetro() { return 2.0 * PI * r; } } // fin de la clase Circulo 2 Herència: Circulo.java // fichero Circulo.java public class Circulo extends Geometria { static int numCirculos=0; public static final double PI=3.14159265358979323846; public double x, y, r; public Circulo(double xx, double yy, double rr) { x=xx; y=yy; r=rr; numCirculos++; } public Circulo(double rr) { x=0.0; y=0.0; r=rr; numCirculos++; } public Circulo(double x, double y, double r) { this.x = x; this.y = y; this.r = r; numCirculos++; } public Circulo(double rr) { this(0,0,rr); } public double area() { return PI * r * r; } public double perimetro() { return 2.0 * PI * r; } } // fin de la clase Circulo 3 Java: this • Els mètodes d’una classe es poden referir a l’objecte d’aquesta mateixa classe amb la paraula this (l’objecte és l’argument implícit). • Classe: Circulo • Objecte: c1 • this.r Æ radi de l’objecte c1 • Els mètodes tenen visibilitat directa de les variables membre d’una classe, i en cas d’haver-hi alguna variable local amb el mateix nom que alguna variable de la classe, llavors es poden accedir a les de classe emprant this.nomvariable: this.x = x; • Si un mètode retorna this vol dir que està retornant l’objecte d’aquesta classe return this 4 Herència: Circulo.java // fichero Circulo.java public class Circulo extends Geometria { static int numCirculos=0; public static final double PI=3.14159265358979323846; public double x, y, r; Emprant this no hi ha confusió de noms de variables public Circulo(double x, double y, double r) { this.x = x; this.y = y; this.r = r; numCirculos++; } public Circulo() { this(0.0, 0.0, 1.0); } public Circulo(double r) { this(0.0, 0.0, r); } public Circulo(Circulo c) { this(c.x, c.y, c.r); } Constructors public double area() { return PI * r * r; } public double perimetro() { return 2.0 * PI * r; } } // fin de la clase Circulo 5 Herència: Circulo.java // fichero Circulo.java public class Circulo extends Geometria { static int numCirculos=0; public static final double PI=3.14159265358979323846; public double x, y, r; Mètode d’objecte S’aplica sobre un objecte de la classe, on l’argument ja està implícit Es pot emprar this Mètode estàtic No actua sobre cap objecte concret, se li passa l’objecte per paràmetre Aquí no es pot emprar this public Circulo(double x, double y, double r) { this.x=x; this.y=y; this.r=r; numCirculos++; } public Circulo() { this(0.0, 0.0, 1.0); } public Circulo(double r) { this(0.0, 0.0, r); } public Circulo(Circulo c) { this(c.x, c.y, c.r); } // método de objeto para comparar círculos public Circulo elMayor(Circulo c) { if (this.r>=c.r) return this; else return c; } // método de clase para comparar círculos public static Circulo elMayor(Circulo c, Circulo d) { if (c.r>=d.r) return c; else return d; } public double area() { return PI * r * r; } public double perimetro() { return 2.0 * PI * r; } } // fin de la clase Circulo 6 Herència: Ejemplo1.java class Ejemplo1 { public static void main(String args[]) { Circulo c1 = new Circulo(1.0, 1.0, 2.0); Circulo c2 = new Circulo(0.0, 0.0, 3.0); Circulo c3 = new Circulo(); // c.r = 1.0; c3 = c2; Circulo c4 = new Circulo(); // c.r = 1.0; c4 = Circulo.elMayor(c1, c2); System.out.println("El mayor radio es " + c.r + "."); c3 = c1.elMayor(c2); System.out.println("El mayor radio es " + c3.r + "."); geometria geometria X=0 Y=0 R=3 X=1 Y=1 R=2 c1 c2 Circulo c5 = new Circulo(c1.elMayor(c2)); c2.r = 5; } } 7 Herència: Ejemplo1.java class Ejemplo1 { public static void main(String args[]) { Circulo c1 = new Circulo(1.0, 1.0, 2.0); Circulo c2 = new Circulo(0.0, 0.0, 3.0); Circulo c3 = new Circulo(); // c.r = 1.0; c3 = c2; Circulo c4 = new Circulo(); // c.r = 1.0; c4 = Circulo.elMayor(c1, c2); System.out.println("El mayor radio es " + c.r + "."); c3 = c1.elMayor(c2); System.out.println("El mayor radio es " + c3.r + "."); geometria geometria X=0 Y=0 R=3 X=1 Y=1 R=2 c1 c2 c3 geometria Circulo c5 = new Circulo(c1.elMayor(c2)); X=0 Y=0 R=1 c2.r = 5; } } 8 Herència: Ejemplo1.java class Ejemplo1 { public static void main(String args[]) { Circulo c1 = new Circulo(1.0, 1.0, 2.0); Circulo c2 = new Circulo(0.0, 0.0, 3.0); Circulo c3 = new Circulo(); // c.r = 1.0; c3 = c2; Circulo c4 = new Circulo(); // c.r = 1.0; c4 = Circulo.elMayor(c1, c2); System.out.println("El mayor radio es " + c.r + "."); c3 = c1.elMayor(c2); System.out.println("El mayor radio es " + c3.r + "."); geometria geometria X=0 Y=0 R=3 X=1 Y=1 R=2 c1 c2 c3 Circulo c5 = new Circulo(c1.elMayor(c2)); c2.r = 5; } } 9 Herència: Ejemplo1.java class Ejemplo1 { public static void main(String args[]) { Circulo c1 = new Circulo(1.0, 1.0, 2.0); Circulo c2 = new Circulo(0.0, 0.0, 3.0); Circulo c3 = new Circulo(); // c.r = 1.0; c3 = c2; Circulo c4 = new Circulo(); // c.r = 1.0; c4 = Circulo.elMayor(c1, c2); System.out.println("El mayor radio es " + c.r + "."); c3 = c1.elMayor(c2); System.out.println("El mayor radio es " + c3.r + "."); geometria geometria X=0 Y=0 R=3 X=1 Y=1 R=2 c1 c2 c3 c4 geometria Circulo c5 = new Circulo(c1.elMayor(c2)); X=0 Y=0 R=1 c2.r = 5; } } 10 Herència: Ejemplo1.java class Ejemplo1 { public static void main(String args[]) { Circulo c1 = new Circulo(1.0, 1.0, 2.0); Circulo c2 = new Circulo(0.0, 0.0, 3.0); Circulo c3 = new Circulo(); // c.r = 1.0; c3 = c2; Circulo c4 = new Circulo(); // c.r = 1.0; c4 = Circulo.elMayor(c1, c2); System.out.println("El mayor radio es " + c.r + "."); c3 = c1.elMayor(c2); System.out.println("El mayor radio es " + c3.r + "."); geometria geometria X=0 Y=0 R=3 X=1 Y=1 R=2 c1 c2 c3 c4 Circulo c5 = new Circulo(c1.elMayor(c2)); c2.r = 5; } } 11 Herència: Ejemplo1.java class Ejemplo1 { public static void main(String args[]) { Circulo c1 = new Circulo(1.0, 1.0, 2.0); Circulo c2 = new Circulo(0.0, 0.0, 3.0); Circulo c3 = new Circulo(); // c.r = 1.0; c3 = c2; Circulo c4 = new Circulo(); // c.r = 1.0; c4 = Circulo.elMayor(c1, c2); System.out.println("El mayor radio es " + c.r + "."); c3 = c1.elMayor(c2); System.out.println("El mayor radio es " + c3.r + "."); Circulo c5 = new Circulo(c1.elMayor(c2)); geometria geometria X=0 Y=0 R=3 X=1 Y=1 R=2 c2 c1 c3 c4 c5 c2.r = 5; } } geometria X=0 Y=0 R=3 Es crea un cercle c5 copiant els valors de c2, és a dir, que es fa una crida al constructor: Circulo(Circulo12 c) Herència: Ejemplo1.java class Ejemplo1 { public static void main(String args[]) { Circulo c1 = new Circulo(1.0, 1.0, 2.0); Circulo c2 = new Circulo(0.0, 0.0, 3.0); Circulo c3 = new Circulo(); // c.r = 1.0; c3 = c2; Circulo c4 = new Circulo(); // c.r = 1.0; c4 = Circulo.elMayor(c1, c2); System.out.println("El mayor radio es " + c.r + "."); c3 = c1.elMayor(c2); System.out.println("El mayor radio es " + c3.r + "."); Circulo c5 = new Circulo(c1.elMayor(c2)); geometria geometria X=0 Y=0 R=3 X=1 Y=1 R=2 c2 c1 X=0 Y=0 R=5 c3 c4 c5 c2.r = 5; } } geometria X=0 Y=0 R=3 Es crea un cercle c5 copiant els valors de c2, és a dir, que es fa una crida al constructor: Circulo(Circulo13 c) Herència: Ejemplo2.java class Ejemplo2 { public static void main(String args[]) { Circulo c1 = new Circulo(1.0, 1.0, 2.0); Circulo c2 = new Circulo(0.0, 0.0, 3.0); geometria c1 geometria c2 Rectangulo r1 = new Rectangulo(2, 0, 4, 3); System.out.println(“Rect. de area:" + r1.area()); Geometria [ ] g; g = new Geometria [3]; g[0]=c1; g[1]=c2; g[2]= r1; geometria r1 g[0] g[1] g[2] double area_elem = g[0].area(); System.out.println(“Elemento de area:" + area_elem); polimorfisme Geometria g1 = new Geometria(); } } 14 Java • Conceptes importants en POO: – Encapsulació: Per controlar l’accés a les classes, variables i mètodes. • Les classes poden ser declarades com públiques o com a package – Si és pública llavors és visible per usuaris que importin el seu paquet. – Si és package llavors només és visible dintre del seu paquet. • Les variables i mètodes poden ser declarades com public, private, protected, package. – Si és privat només és accessible des de la pròpia classe – Si és protected llavors poden accedir-hi les seves subclasses – Herència: Una classe pot derivar d’una altra – Polimorfisme (Sobrecàrrega): Un objecte pot tenir un tractament (mètode) diferent depenent del seu tipus • Varis mètodes amb el mateix nom es diferencien pel nombre i tipus d’arguments • Quan es crida al mètode, depenent del paràmetre, s’executarà un mètode o un altre • Una classe pot redefinir un mètode heretat de una superclasse. En aquest cas el mètode tindrà els mateixos arguments que a la superclasse. 15 Java: Encapsulació i Accessibilitat • • • Un package és accessible si els seus directoris i fitxers són accessibles Una classe és accessible per a totes les demés classes del package, tant si és públic com si no ho és Accessibilitat dels membres(variables i mètodes) de la classe – Tots els membres de la classe són accessibles des de dins la pròpia classe – Els membres privats només són accessibles des de la pròpia classe – Les subclasses també hereden els membres privats de la superclasse, però només poden accedir a ells a través de mètodes (no privats) – D’es d’una classe d’un package, es té accés a tots els membres no privats de les demés classes del package – Un membre d’una classe és accessible des de fora del package si és públic, o bé si la classe que accedeix es sub-classe i el membre és protected – Si el constructor d’una classe és privat, només un mètode estàtic de la pròpia classe pot crear objectes. 16 Encapsulació i Accessibilitat 17 Exemple: Lloguer de vehicles Una agència de lloguer de vehicles sense conductor disposa de: • Camions Utilitaris • Turismes Familiars 18 Vehiculo.java // fichero Vehiculo.java public abstract class Vehiculo { protected String matricula; protected boolean alquilado; public Vehiculo(String mat, boolean alq) { matricula=mat; alquilado=alq; } public abstract void alquilar(int dia); public abstract void devolver(int dia); public abstract void showInfo(); } // fin de clase Vehiculo 19 Turismo.java // fichero Turismo.java public class Turismo extends Vehiculo { protected double precioKm; protected int kmAlquiler, kmDevolucion; protected static int numTurismos, numTurAlquilados; public Turismo(String mat, boolean alq, double prKm) { // llamada constructor de la superclase. Debe ser // la primera sentencia del constructor super(mat, alq); precioKm = prKm; kmAlquiler = 0; kmDevolucion = 0; numTurismos++; } public void alquilar(int kmAlq) { if (alquilado == true) System.out.println("El turismo " + matricula + " esta ya alquilado."); else { kmAlquiler = kmAlq; System.out.println("Se alquila un turismo con " + kmAlquiler + "km."); numTurAlquilados++; alquilado = true; } } 20 Turismo.java II public void devolver(int kmDev) { if (alquilado == true) { kmDevolucion = kmDev; System.out.print("Se devuelve un turismo con " + kmDevolucion + "km. "); System.out.println("Precio a abonar: " + (kmDevolucion-kmAlquiler)*precioKm + " Euros"); numTurAlquilados--; alquilado = false; } else System.out.println("El turismo " + matricula + " no esta alquilado."); } public void showInfo() { System.out.println("\nDatos de un Turismo:"); System.out.println("Matricula: " + matricula); System.out.println("Alquilado: " + ((alquilado==true)? "Si": "No")); System.out.println("Precio por km: " + precioKm + " Euros"); System.out.println("Numero total de turismos: " + numTurismos); System.out.println("Numero de turismos alquilados: " + numTurAlquilados); } } // fin de clase Turismo 21 Camion.java // fichero Camion.java public class Camion extends Vehiculo { protected double precioDia; protected int diaAlquiler, diaDevolucion; protected static int numCamiones, numCamAlquilados; public Camion(String mat, boolean alq, double prD) { // llamada constructor de la superclase. Debe ser // la primera sentencia del constructor super(mat, alq); precioDia = prD; diaAlquiler = 0; diaDevolucion = 0; numCamiones++; } 22 Camion.java II public void alquilar(int diaAlq) { if (alquilado==true) { System.out.println("El camion " + matricula + " esta ya alquilado."); } else { diaAlquiler = diaAlq; System.out.println("Se alquila un camion el dia " + diaAlquiler + "."); numCamAlquilados++; alquilado = true; } } public void devolver(int diaDev) { if (alquilado==true) { diaDevolucion = diaDev; System.out.print("Se devuelve un camion el dia " + diaDevolucion + ". "); System.out.println("Precio a abonar: " + (diaDevolucion-diaAlquiler)*precioDia + " Euros"); numCamAlquilados--; alquilado = false; } else System.out.println("El camion " + matricula + " no esta alquilado."); } 23 Camion.java III public void showInfo() { System.out.println("\nDatos de un Camion:"); System.out.println("Matricula: " + matricula); System.out.println("Alquilado: " + ((alquilado==true)? "Si": "No")); System.out.println("Precio por dia: " + precioDia + " Euros"); System.out.println("Numero total de camiones: " + numCamiones); System.out.println("Numero de camiones alquilados: " + numCamAlquilados); } } // fin de clase Camion 24 AgenciaAlquiler.java // fichero AgenciaAlquiler.java class AgenciaAlquiler { public static void main(String [] arg) { Vehiculo [] avis = new Vehiculo[4]; avis[0] = new Camion("SS-4386-AN", false, 100); avis[1] = new Turismo("BI-6666-ZZ", false, 0.3); avis[2] = new Turismo("HU-1976-A", false, 0.4); avis[3] = new Camion("VI-1234-HL", false, 120); System.out.println("\nSE ALQUILAN DOS VEHICULOS:"); avis[2].alquilar(23000); // alquilar turismo con 23000 km avis[3].alquilar(5); // alquilar camion el dia 5 // intento de volver a alquilar avis[2].alquilar(23000); avis[3].alquilar(5); 25 AgenciaAlquiler.java II System.out.println("\nSE IMPRIMEN LOS DATOS " + "DE LOS VEHICULOS:"); for (int i=0; i<avis.length; i++) avis[i].showInfo(); System.out.println("\nSE DEVUELVEN DOS VEHICULOS:"); avis[2].devolver(25000); // devolver turismo con 25000 km avis[3].devolver(9); // devolver camion el dia 9 // intento de devolver de nuevo avis[2].devolver(25000); avis[3].devolver(9); System.out.println("\nYa he terminado"); } // fin de main() } // fin de la clase AgenciaAlquiler 26 Sortida per pantalla SE ALQUILAN DOS VEHICULOS: Se alquila un turismo con 23000km. Se alquila un camion el dia 5. El turismo HU-1976-A esta ya alquilado. El camion VI-1234-HL esta ya alquilado. SE IMPRIMEN LOS DATOS DE LOS VEHICULOS: Datos de un Camion: Matricula: SS-4386-AN Alquilado: No Precio por dia: 100.0 Euros Numero total de camiones: 2 Numero de camiones alquilados: 1 Datos de un Turismo: Matricula: BI-6666-ZZ Alquilado: No Precio por km: 0.3 Euros Numero total de turismos: 2 Numero de turismos alquilados: 1 Datos de un Turismo: Matricula: HU-1976-A Alquilado: Si Precio por km: 0.4 Euros Numero total de turismos: 2 Numero de turismos alquilados: 1 Datos de un Camion: Matricula: VI-1234-HL Alquilado: Si Precio por dia: 120.0 Euros Numero total de camiones: 2 Numero de camiones alquilados: 1 SE DEVUELVEN DOS VEHICULOS: Se devuelve un turismo con 25000km. Precio a abonar: 800.0 Euros Se devuelve un camion el dia 9. Precio a abonar: 480.0 Euros El turismo HU-1976-A no esta alquilado. El camion VI-1234-HL no esta alquilado. Ya he terminado 27 Bibliografia • Llibres – – – – – Aprenda Java como si estuviera en Primero (Navarra) Thinking in Java, Bruce Eckel Java How to Program, Deitel& Deitel Beginning Java 2, Horton Java in a Nutshell, Flanagan & Ferguson • Internet – Sun’s Java Pages – Java API specification 28