31
Problem a 1. Escribirun program a para calcularelperím etro de una circunferencia siguiendo eldiálogo: radio?__ perímetro=Nº Solución 1. Con program a ad-hoc class Programa{ static public void main(String[]args) throws IOException { double r=U.readDouble(“radio?”); U.println(“perímetro=” + 2*Math.PI*r); } }

class Circulo extends Circunferencia Circunferencia perimetro Circunferenciaradio Circulo area Circulo

Embed Size (px)

Citation preview

Page 1: class Circulo extends Circunferencia Circunferencia perimetro Circunferenciaradio Circulo area Circulo

Problema 1. Escribir un programa para calcular el perímetro de una circunferencia siguiendo el diálogo:

radio?__ perímetro=Nº Solución 1. Con programa ad-hoc class Programa{ static public void main(String[]args) throws IOException { double r=U.readDouble(“radio?”); U.println(“perímetro=” + 2*Math.PI*r); } }

Page 2: class Circulo extends Circunferencia Circunferencia perimetro Circunferenciaradio Circulo area Circulo

Solución 2. Con clase para circunferencias class Circunferencia{ private double r; public Circunferencia(double x){ if(x<=0) U.abortar(“radio<=0”); r=x; } public double perimetro(){ return 2*Math.PI*r; } } class Programa{ static public void main(String[]args) throws IOException{ Circunferencia c=new Circunferencia( U.readDouble(“radio?”)); U.println(“perímetro=” + c.perimetro()); } }

Page 3: class Circulo extends Circunferencia Circunferencia perimetro Circunferenciaradio Circulo area Circulo

Problema 2. Calcular el área y el perímetro de un círculo Solución 1. Modificar clase Circunferencia agregando método área Solución 2. Usar (y escribir) nueva clase Circulo que:

extienda la clase Circunferencia con método área herede las otras componentes (datos y métodos).

U.println(“Calcular área y perímetro de círculo”); Circulo c=new Circulo(U.readDouble(“radio?”));

//uso de método de clase Circulo U.println(“área=”+c.area()); //uso de método heredado de clase Circunferencia U.println(“perímetro=”+c.perimetro());

Page 4: class Circulo extends Circunferencia Circunferencia perimetro Circunferenciaradio Circulo area Circulo

//clase base o superior class Circunferencia{ protected double r;//visible en clase y extensiones public Circunferencia(double x){ r=x; if(r<=0) U.abortar(“radio<=0”); } public double perimetro(){ return 2*Math.PI*r; } } //clase extendida o derivada class Circulo extends Circunferencia{ public double area(){ return Math.PI*r*r; } public Circulo(double x){//constructor super(x);//invocar ctor de clase superior } }

Page 5: class Circulo extends Circunferencia Circunferencia perimetro Circunferenciaradio Circulo area Circulo

class Circulo extends Circunferencia

Circunferencia

perimetro

Circunferencia radio

Circulo

area

Circulo

Page 6: class Circulo extends Circunferencia Circunferencia perimetro Circunferenciaradio Circulo area Circulo

Problema 3. Calcular área y perímetro de un círculo o un cuadrado Circulo(1) o Cuadrado(2)? __ radio?__ o lado?__ area=Nº perimetro=Nº Programa: int n=U.readInt(“Circulo(1) o Cuadrado(2)?”); if(n==1){ Circulo c=new Circulo(U.readDouble(“radio?”)); U.println(“area=”+c.area()); U.println(“perimetro=”+c.perimetro()); }else if(n==2){ Cuadrado c=new Cuadrado(U.readDouble(“lado?”)); U.println(“area=”+c.area()); U.println(“perimetro=”+c.perimetro()); }else U.abortar(“debe ser 1 o 2”);

Page 7: class Circulo extends Circunferencia Circunferencia perimetro Circunferenciaradio Circulo area Circulo

Solución 1. Con clases independientesclass Circulo{protected double r;public Circulo(double x){ r=x; if(r<=0) U.abortar(“radio<=0”);}public double area(){return Math.PI*r*r;}public double perimetro(){return 2*Math.PI*r;}} class Cuadrado{protected double a;public Cuadrado x){ a=x; if(a<=0) U.abortar(“lado<=0”);}public double area(){return a*a;}public double perimetro(){return 4*a;}}

Page 8: class Circulo extends Circunferencia Circunferencia perimetro Circunferenciaradio Circulo area Circulo

Solución 2. Con jerarquía de clasesclass Figura{protected double x;public Figura(double x){ this.x=x; if(x<=0) U.abortar(“<=0”);}} class Circulo extends Figura{public Circulo(double x){super(x);}public double area(){return Math.PI*x*x;}public double perimetro(){return 2*Math.PI*x;}} class Cuadrado extends Figura{public Cuadrado(double x){super(x);}public double area(){return x*x;}public double perimetro(){return 4*x;}}

Page 9: class Circulo extends Circunferencia Circunferencia perimetro Circunferenciaradio Circulo area Circulo

Solución 3. Con métodos ficticios (redefinidos en extensiones) class Figura{ protected double x; public Figura(double x){ this.x=x; if(x<=0) U.abortar(“<=0”); } public double area(){return 0;} public double perimetro(){return 0;} } Corolario. Programa usuario más breve Figura f; switch( U.readInt(“Circulo(1) o Cuadrado(2)?”) ){ case 1: f=new Circulo(U.readDouble(“radio?”)); break; case 2: f=new Cuadrado(U.readDouble(“lado?”)); break; default: U.abortar(“1 o 2”); } U.println(“area=”+f.area()); U.println(“perimetro=”+f.perimetro());

Page 10: class Circulo extends Circunferencia Circunferencia perimetro Circunferenciaradio Circulo area Circulo

Enlace Dinámico (dynamic binding) f=new Circulo(…); f=new Cuadrado(…); referencia a objeto de clase Figura puede apuntar también a objetos de

clase extendidas Circulo y Cuadrado objeto de clase extendida es un objeto de clase base (círculos y

cuadrados son figuras) f.area() si f apunta a un objeto de clase Cuadrado, se invoca método area de clase Cuadrado Circulo , se invoca método area de clase Circulo x objeto clase Cuadrado

f referencia clase x objeto clase

Figura Circulo

Page 11: class Circulo extends Circunferencia Circunferencia perimetro Circunferenciaradio Circulo area Circulo

Solución 4: Con clase abstracta que obliga a redefinir métodos

abstract class Figura{protected double x;public Figura(double x){ this.x=x; if(x<=0) U.abortar(“debe ser >0”);}abstract public double area();abstract public double perimetro();}Notas•no permite crear objetos, no admite new Figura()•debe tener al menos un método abstracto:

abstract encabezamiento;•obliga a clases extendidas a redefinir métodos abstractos•permite definir otras figuras

Page 12: class Circulo extends Circunferencia Circunferencia perimetro Circunferenciaradio Circulo area Circulo

class Rectangulo extends Figura{protected double y;public Rectangulo(double x,double y){ super(x); this.y=y; if(y<=0) U.abortar(“<=0”);}public double area(){return x*y;}public double perimetro(){return 2*(x+y);}} class Triangulo extends Figura{protected double y,z;public Triangulo(double x,double y,double z){ super(x); this.y=y; this.z=z; if(y<=0 || z<=0 || x+y<=z || x+z<=y || y+z<=x) U.abortar(“no forman triangulo”);}public double perimetro(){return x+y+z;}public double area(){ double s=(x+y+z)/2; return Math.sqrt(s*(s-x)*(s-y)*(s-z));}}

Page 13: class Circulo extends Circunferencia Circunferencia perimetro Circunferenciaradio Circulo area Circulo

Problema . Escriba la clase abstracta Cuerpo y las clases extendidas Cubo, Esfera y Caja para el siguiente programa que permite calcular el volumen y el área de un cubo, una esfera, o una caja (paralelepípedo)

Cuerpo c; switch(U.readInt(“Cubo(1),Esfera(2),o Caja(3)?”)) { case 1: c=new Cubo(U.readDouble(“lado?”)); break; case 2: c=new Esfera(U.readDouble(“radio?”)); break; case 3: c=new Caja(U.readDouble(“largo?”), U.readDouble(“ancho?”), U.readDouble(“alto?”)); break; default: U.abortar(“1, 2 o 3”); } U.println(“volumen=” + c.volumen()); U.println(“area=” + c.area());

Nota. El área de la esfera es 4r2 y el volumen es 4/3r3

Page 14: class Circulo extends Circunferencia Circunferencia perimetro Circunferenciaradio Circulo area Circulo

abstract class Cuerpo{ protected double x; public Cuerpo(double x){ this.x=x; if(x<=0) U.abortar(“<=0”); } abstract double area(); abstract double volumen(); } class Esfera extends Cuerpo{ public Esfera(double x){super(x);} public double area(){return 4*Math.PI*x*x;} public double volumen(){return Math.PI*x*x*x*4/3;} } class Cubo extends Cuerpo{ public Cubo(double x){super(x);} public double area(){return 6*x*x;} public double volumen(){return x*x*x;} }

Page 15: class Circulo extends Circunferencia Circunferencia perimetro Circunferenciaradio Circulo area Circulo

class Caja extends Cuerpo{ protected double y, z; public Caja(double x,double y,double z){ super(x); this.y=y; this.z=z; if(y<=0 || z<=0) U.abortar(“<=0”); } public double area(){ return 2*(x*y + x*z + y*z); } public double volumen(){ return x*y*z; } } Nota. Un cubo es también una caja class Cubo extends Caja{ public Cubo(double x){super(x,x,x);} }

Page 16: class Circulo extends Circunferencia Circunferencia perimetro Circunferenciaradio Circulo area Circulo

Solución 2. Con interface clase base abstracta sólo con métodos implicitamente abstractos sin datos interface Cuerpo { public double area(); public double volumen(); }

Page 17: class Circulo extends Circunferencia Circunferencia perimetro Circunferenciaradio Circulo area Circulo

class Esfera implements Cuerpo{ protected double r; public Esfera(double x){r=x;} public double area(){ return 4*Math.PI*r*r; } public double volumen(){ return Math.PI*r*r*r*4/3; } } class Cubo implements Cuerpo{ protected double a; public Cubo(double x){a=x;} public double area(){return 6*a*a;} public double volumen(){return a*a*a;} }

Page 18: class Circulo extends Circunferencia Circunferencia perimetro Circunferenciaradio Circulo area Circulo

class Caja implements Cuerpo{ protected double l,a,h;//largo, ancho y altura public Caja(double x,double y,double z){ l=x; a=y; h=z; if(x<=0 || y<=0 || z<=0) U.abortar(“<=0”); } public double area(){ return 2*(l*a + l*h + a*h); } public double volumen(){ return l*a*h; } } Nota. Un cubo es también una caja class Cubo extends Caja{ public Cubo(double x){super(x,x,x);} }

Page 19: class Circulo extends Circunferencia Circunferencia perimetro Circunferenciaradio Circulo area Circulo

Object: clase raíz de toda la jerarquía de herencia de Java class Object { //entrega la dir del objeto en memoria //en la forma “NombreClase@nºhexadecimal” (base 16) public String toString(){ return ...; } //entrega true sólo si es el mismo objeto public boolean equals(Object x){ return this==x;//compara referencias } ...//otros métodos }

Page 20: class Circulo extends Circunferencia Circunferencia perimetro Circunferenciaradio Circulo area Circulo

Toda clase extiende (implícita o explicitamente) a Object class Fraccion extends Object{ protected int a, b; ... //redefinición de métodos de clase Object public String toString(){ return a+”/”+b; } public boolean equals(Object x){ Fraccion f=(Fraccion)x; //casting return a*f.b == b*f.a;//compara objetos } }

casting para considerar x como Fraccion error si x no es de clase Fraccion (o extensión)

Page 21: class Circulo extends Circunferencia Circunferencia perimetro Circunferenciaradio Circulo area Circulo

Métodos genéricos (aplicables a objetos de distintas clases) //invertir n objetos de arreglo x static public void invertir(Object[]x,int n){ for(int i=0; i<n/2; ++i) intercambiar(x,i,n-i-1); } //intercambiar x[i] con x[j] static public void intercambiar(Object[]x,int i,int j){ Object aux=x[i]; x[i]=x[j]; x[j]=aux; } //mostrar un arreglo de objetos static public void mostrar(Object[]x){ for(int i=0; i<x.length; ++i) U.println(x[i].toString()); } si toString no existe en clase de x[i], se hereda de clase Object se puede escribir sólo U.println(x[i]);

Page 22: class Circulo extends Circunferencia Circunferencia perimetro Circunferenciaradio Circulo area Circulo

Uso de métodos genéricos //para arreglo de strings String[]s={“C”,”B”,”A”,”B”,”C”}; mostrar(s);invertir(s,s.length);mostrar(s); //para arreglo de fracciones Fraccion[]f={new Fraccion(), new Fraccion(1,2), new Fraccion(“123/4567”), new Fraccion(5)}; mostrar(f);invertir(f,f.length);mostrar(f); //para arreglo heterogeneo Object[]a={“A”,new Fraccion(1/2),”B”}; mostrar(a);invertir(a,a.length);mostrar(a);

Page 23: class Circulo extends Circunferencia Circunferencia perimetro Circunferenciaradio Circulo area Circulo

Búsqueda (de un objeto en un arreglo de objetos) //buscar objeto x en arreglo y de n objetos //entregar índice de 1ªaparición (–1 si no está) static public int indice(Object x,Object[]y,int n){ for(int i=0; i<n; ++i) if(y[i].equals(x)) return i; return –1; } Uso indice(“A”,s,s.length) entrega 2 indice(new Fraccion(2,4),f,f.length) entrega 1 puesto que f[1] es new Fraccion(1,2) indice(“A”,a,a.length) entrega 0

Page 24: class Circulo extends Circunferencia Circunferencia perimetro Circunferenciaradio Circulo area Circulo

Comparable: Interface predefinida para clases que admiten comparar objetos interface Comparable{ public int compareTo(Object x); } class Fraccion implements Comparable{ ... //redefinición de compareTo de Comparable public int compareTo(Object x){ Fraccion f=(Fraccion)x; return a*f.b – b*f.a; } } Nota clase String extiende Object e implementa Comparable

Page 25: class Circulo extends Circunferencia Circunferencia perimetro Circunferenciaradio Circulo area Circulo

Problema. Ordenar un arreglo de n objetos (comparables) encabezamiento static public void ordenar(Comparable[]x,int n) Invocación (ejemplos) String[]s={...}; Fraccion[]f={...}; ordenar(s,s.length); ordenar(f,f.length); Situación inicial: arreglo desordenado Situación final: arreglo ordenado

Page 26: class Circulo extends Circunferencia Circunferencia perimetro Circunferenciaradio Circulo area Circulo

Solución 1. Algoritmo de selección y reemplazo/intercambio Repetir n veces seleccionar el menor intercambiar menor con el primero ¿situación intermedia (invariante)? ip im ip: índice del primero (de los que aún están desordenados) im: índice del menor (entre los desordenados) Si se intercambia x[ip] con x[im] y se avanza ip, entonces la invariante se restablece (mantiene)

Page 27: class Circulo extends Circunferencia Circunferencia perimetro Circunferenciaradio Circulo area Circulo

static public void ordenar(Comparable[]x,int n){ //repetir n veces for(int ip=0; ip<n; ++ip)//para ip=0,...,n-1 { //seleccionar el (indice del) menor int im=ip; for(int i=ip+1; i<n; ++i) if(x[i].compareTo(x[im])<0) im=i; //intercambiar menor con el primero intercambiar(x,im,ip); } } Algoritmo O(n2) las n iteraciones realizan n-1, n-2, ..., 1 comparaciones total de comparaciones: i, para i=1,...,n-1=n(n-1)/2=n2/2 - n/2 orden de magnitud: n2 ej, si n=100, se realizan del orden de 10.000 comparaciones

Page 28: class Circulo extends Circunferencia Circunferencia perimetro Circunferenciaradio Circulo area Circulo

Búsqueda secuencial para arreglo ordenado: O(n), pero peor caso realiza en promedio n/2 (y no n) comparaciones int indice(Comparable x,Comparable[]y,int ip,int iu){ //recorrer todos los índices (de 1º a último) for(int i=ip; i<=iu; ++i){ //si y[i]=x, devolver índice i int c=y[i].compareTo(x); if(c==0) return i; //si y[i]>x, no está (pq y está ordenado) if(c>0) break; } return –1; } recursivamente if(ip>iu) return –1; int c=y[ip].compareTo(x); if(c==0) return ip; return c>0? -1: indice(x,y,ip+1,iu);

Page 29: class Circulo extends Circunferencia Circunferencia perimetro Circunferenciaradio Circulo area Circulo

Problema. Programar el algoritmo de búsqueda binaria (para buscar eficientemente en arreglo ordenado)

encabezamiento static public int indice( Comparable x,Comparable[]y,int ip,int iu) ¿algoritmo? Comparar x con elemento que está en la mitad del arreglo y Si son iguales, devolver índice de mitad Si x es menor, buscar en primera mitad del arreglo (descartando segunda mitad) Si x es mayor, buscar en segunda mitad del arreglo

(descartando primera mitad) Repetir mientras queden elementos. Devolver –1 si x no está en arreglo y.

Page 30: class Circulo extends Circunferencia Circunferencia perimetro Circunferenciaradio Circulo area Circulo

static public int indice (Comparable x,Comparable[]y,int ip,int iu){ //repetir mientras queden elementos while(ip<=iu){ //comparar x con elemento que está en la mitad

int im=(ip+iu)/2; //indice del medio int c=x.compareTo(y[im]); //si son iguales, devolver índice de mitad if(c==0) return im; //si x es menor, buscar en 1ª mitad del arreglo if(c<0) iu=im–1;//”subir” índice del último //si x es mayor, buscar en 2ª mitad del arreglo else ip=im+1;//”bajar” índice del primero } //devolver –1 si x no está en arreglo y. return –1; }

Page 31: class Circulo extends Circunferencia Circunferencia perimetro Circunferenciaradio Circulo area Circulo

Ejemplo de uso: static public void main(String[]args){ String[]mes={“abril”,...,”septiembre”}; String[]month={“april”,..., “september”}; int i=indice(args[0],mes,0,mes.length-1); U.println( i<0? “mes incorrecto”: month[i]); } invocación java TraducirMes mayo may java TraducirMes martes mes incorrecto