310 likes | 413 Views
Programación Problemas del tema 8. Definición y diseño de clases. PROBLEMA 1:
E N D
ProgramaciónProblemas del tema 8 Definición y diseño de clases. Alfonso Jiménez
PROBLEMA 1: • Se pretende realizar un programa que sea capaz de operar con números complejos o imaginarios. Cada número complejo estará compuesto por una parte real y una parte imaginaria (ambos de tipo real o doble precisión). En cuanto al comportamiento u operaciones que pueden sufrir tendremos: • Creación de un nuevo número complejo. Se podrá crear de dos maneras diferentes: dando la parte real y la parte imaginaria del número complejo directamente o no dando ningún valor y entonces se creará el numero complejo (0,0). • Consulta de los valores de la parte real y la parte imaginaria. • Suma de dos números complejos. • Resta de números complejos. • Multiplicación de complejos. • División de complejos (teniendo el cuenta el conjugado del denominador). • Módulo de un número complejo. • Conversión a cadena de caracteres. Alfonso Jiménez
Case Complejo • // Clase para la definición de números complejos. • class complejo { • // atributos privados • private double preal; • private double pimag; • // Constructores de la clase • public complejo() { • preal = 0; • pimag = 0; • } • public complejo(double r, double i) { • preal = r; • pimag = i; • } • // Consultoras • public double preal() { • return (this.preal); • } • public double pimag() { • return (this.pimag); • } Alfonso Jiménez
// Operaciones aritméticas public complejo sumaC(complejo c) { complejo aux = new complejo(); aux.preal = preal+c.preal; aux.pimag = pimag+c.pimag; return(aux); } public complejo restaC(complejo c) { return (this.sumaC(new complejo(-c.preal,-c.pimag))); } /* Otra forma posible de expresar la operación restaC public complejo restaC2(complejo c) { return (new complejo(preal-c.preal,pimag-c.pimag)); } */ public complejo prodC(complejo c) { return (new complejo(preal*c.preal-pimag*c.pimag, preal*c.pimag+pimag*c.preal)); } public complejo conjugado() { return (new complejo(this.preal, -this.pimag)); } public double modulo() { return (Math.sqrt(preal*preal+pimag*pimag)); } Alfonso Jiménez
// La división se efectúa multiplicando dividendo y divisor // por el conjugado del divisor. Puede darse una excepción // de división por 0 (denominador=(0,0)) public complejo divisionC (complejo den) { complejo cden = den.conjugado(); complejo mult1 = cden.prodC(this); complejo mult2 = den.prodC(cden); if (mult2.preal!=0) return(new complejo (mult1.preal/mult2.preal, mult1.pimag/mult2.preal)); else return null; // división por cero } // Conversion a cadena de caracteres public String toString() { return (preal+" + "+pimag+'i'); } } // fin de la clase complejo Alfonso Jiménez
Clase pruebaComplejo: import nsIO.*; class pruebaComplejo { public static void main (String args[]) { input fent=new input(); output fsal=new output(); // declaraciones complejo c1; complejo c2; complejo aux; double pr,pi; fsal.writeln("Oper. básicas con números complejos."); fsal.writeln("Parte real del primer numero complejo:"); pr=fent.readdouble(); fsal.writeln("Ahora la parte imaginaria:"); pi=fent.readdouble(); c1=new complejo(pr,pi); Alfonso Jiménez
fsal.writeln("Parte real del segundo numero complejo:"); pr=fent.readdouble(); fsal.writeln("Ahora la parte imaginaria:"); pi=fent.readdouble(); c2=new complejo(pr,pi); aux=c1.sumaC(c2); fsal.writeln("La suma vale:"+aux.toString()); aux=c1.restaC(c2); fsal.writeln("La resta vale:"+aux.toString()); aux=c1.prodC(c2); fsal.writeln("El producto vale:"+aux.toString()); fsal.writeln("El modulo del primero vale:"+c1.modulo()); fsal.writeln("El modulo del segundo vale:"+c2.modulo()); aux=c1.divisionC(c2); if (aux!=null) fsal.writeln("La division vale:"+aux.toString()); else fsal.writeln("Intento de division por cero."); } // de main } // fin de la clase pruebaComplejo Alfonso Jiménez
PROBLEMA 2: • Se pretende crear una clase que permita representar números racionales (numerador/denominador) y operar con ellos. Los números se guardarán lo más simplificados posible. • Las operaciones que se pueden realizar sobre los números racionales serán: • Sumar, restar, multiplicar y dividir 2 racionales. • Comparar 2 números racionales. • Comprobar si son iguales. • Devolver el valor real de un racional. • Conversión de un racional a un String. Alfonso Jiménez
LISTADO DEL PROGRAMA: • Clase Racional • class racional { • // ******************* atributos *********************** • private int num; // numerador • private int den; // denominador • // ********** Métodos privados de la clase ************* • // método para calcular el máximo común divisor de dos • // números enteros positivos. Algoritmo de Euclides • private int mcd(int a, int b) { • int r; • while (a % b != 0) { • r = a % b; • a = b; • b = r; • } • return b; • } • // método privado para simplificar una fracción que • // represente un racional. • // Por ejemplo: 60/-18 --simplifica--> -10/3 • // num != 0 && den != 0 Alfonso Jiménez
private void simplifica() { // es inf? if (den==0 && num !=0) num=1; // es 0? else if (den!=0 && num==0) den=1; // es una fracción? -> normalizarla else if (num!=0 && den!=0) { // valores absolutos: int absNum = Math.abs(num); int absDen = Math.abs(den); // signo del denominador: int signo = den/absDen; int s = mcd(absNum,absDen); num = signo*(num/s); den = signo*(den/s); } } // *********** Constructores de la clase ************* public racional (int num, int den) { this.num = num; this.den = den; // simplificación de la fracción simplifica(); } Alfonso Jiménez
public racional (int num) { this.num = num; this.den = 1; } // *********** Operaciones aritméticas ************* // Para mantener las convenciones aritméticas habituales // se han definido como operaciones "static" public static racional suma (racional r1, racional r2) { racional sum = new racional(r1.num*r2.den+r1.den*r2.num, r1.den*r2.den); sum.simplifica(); return sum; } public static racional resta (racional r1, racional r2) { racional dif = new racional(r1.num*r2.den-r1.den*r2.num, r1.den*r2.den); dif.simplifica(); return dif; } public static racional multiplica (racional a, racional b) { racional mult = new racional(a.num*b.num, a.den*b.den); mult.simplifica(); return mult; } Alfonso Jiménez
public static racional inverso (racional a) { return new racional(a.den,a.num); } public static racional dividir (racional dn, racional dd) { return multiplica(dn, inverso(dd)); } // conversión a double: this.den != 0 public double todouble () { return ((double)num/(double)den); } public String toString() { return this.num+"/"+this.den; } public boolean equals (racional r) { return (num==r.num && den==r.den); } Alfonso Jiménez
public int compareTo (racional r) { if (this.equals(r)) return 0; else // supongamos que no es una indeterminación, // esto es num y den no son simultáneamente 0 if (den == 0) return 1; else if (r.den==0) return -1; else // comparar números double if (this.todouble() > r.todouble()) return 1; else return -1; } } // Fin de la clase racional Alfonso Jiménez
Clase pruebaRacional import nsIO.*; class pruebaRacional { static output fsal = new output(); static input fent = new input(); static int menu(){ int opc; do{ fsal.writeln(" == MENU - Numeros Racionales =="); fsal.writeln(""); fsal.writeln("1.- Intoducir 2 números racionales."); fsal.writeln("2.- Suma de los dos racionales."); fsal.writeln("3.- Resta de los dos racionales."); fsal.writeln("4.- Multiplicación de los dos racionales."); fsal.writeln("5.- División de los dos racionales."); fsal.writeln("6.- Inverso del primer racional."); fsal.writeln("7.- Inverso del segundo racional."); fsal.writeln("8.- Son iguales??."); fsal.writeln("9.- Compararlos."); fsal.writeln("10.- Valor real del primer racional."); fsal.writeln("11.- Valor real del segundo racional."); fsal.writeln("12.- Los 2 racionales valen:"); fsal.writeln("0.- SALIR."); fsal.writeln(""); fsal.writeln("Elige una opcion:"); opc=fent.readint(); } while ((opc<0)||(opc>12)); return opc; } /* de menu */ Alfonso Jiménez
static racional crea_racional () { int n,d; racional aux; fsal.writeln("Dame el numerador:"); n=fent.readint(); fsal.writeln("Su denominador:"); d=fent.readint(); aux=new racional(n,d); return(aux); } public static void main (String args[]){ int opc,comp; racional r1,r2,aux; do{ opc=menu(); switch (opc){ case 1: fsal.writeln("Introduce el primer numero racional:"); r1=crea_racional(); fsal.writeln("Introduce el segundo:"); r2=crea_racional(); break; case 2: aux=racional.suma(r1,r2); fsal.writeln("La suma vale: "+aux.toString()); break; case 3: aux=racional.resta(r1,r2); fsal.writeln("La resta vale: "+aux.toString()); break; Alfonso Jiménez
case 4: aux=racional.multiplica(r1,r2); fsal.writeln("La multiplicacion vale: "+aux.toString()); break; case 5: aux=racional.dividir(r1,r2); fsal.writeln("La division vale: "+aux.toString()); break; case 6: aux=racional.inverso(r1); fsal.writeln(“Inverso del primero: "+aux.toString()); break; case 7: fsal.writeln(“Inverso del segundo: "+racional.inverso(r2).toString()); break; case 8: if (r1.equals(r2)) fsal.writeln("Los racionales son iguales."); else fsal.writeln("Los racionales NO son iguales."); break; case 9: comp=r1.compareTo(r2); if (comp==0) fsal.writeln("Los racionales son iguales."); else if (comp==1) fsal.writeln("El primero es el mayor."); else fsal.writeln("El segundo es el mayor."); break; case 10: fsal.writeln("Valor real del primero: "+r1.todouble()); break; Alfonso Jiménez
case 11: fsal.writeln("Valor real del segund: "+r2.todouble()); break; case 12: fsal.writeln("El primero vale: "+r1.toString()); fsal.writeln("El segundo: "+r2.toString()); break; case 0: break; } } while (opc !=0); } /* de main */ } /* de la clase */ Alfonso Jiménez
PROBLEMA 3: • Una academia pretende informatizar la gestión de sus dos grupos de alumnos. Cada grupo está compuesto de un máximo de 10 alumnos. De cada alumno interesa saber: su nombre, su número de matrícula y las notas de los 2 exámenes realizados, así como la media aritmética de esas 2 notas. Respecto a los grupos, de cada uno tendremos el vector que contiene los alumnos, el número real de alumnos y el número de matrícula que tendrá el siguiente alumno que se matricule (en cualquiera de los grupos). El número de matrícula es común para los dos grupos y empezará en 100. • Las operaciones que se pueden realizar con cada grupo son: • Añadir un alumno, comprobando si cabe en el grupo y asignándole un número de matrícula. Para realizar esta operación, hará falta el nombre de alumno y sus dos notas. • Borrar un alumno conociendo el número de matrícula. • Cálculo de la nota media del grupo completo (las 2 notas de todos los alumnos del grupo). • Consulta del siguiente número de matrícula a asignar. • Conversión de todos los datos del grupo a un String. Alfonso Jiménez
ESTRATEGIA DE RESOLUCIÓN: • Se tienen 2 entidades o conceptos diferentes: el alumno y el grupo, que dará lugar a dos clases diferentes, la clase alumno y la clase grupo. • La clase alumno tendrá 4 atributos privados: • Nombre • Nota1 • Nota2 • Matrícula • Que definen la estructura que tendrá cada objeto alumno creado de esa clase. En cuanto al comportamiento de los objetos o métodos que contendrá la clase, tendremos: • Un constructor de los objetos, que necesitará el nombre, las dos notas y el número de la matrícula del objeto alumno que está creando. • Cuatro métodos consultores que devolverán los valores de cada uno de los atributos privados que tiene cada objeto (hay que recordar que los atributos son privados). • Un consultor que devuelva la media aritmética de las dos notas del alumno. • Un consultor que convierta los datos de un alumno en un String. Alfonso Jiménez
La clase grupo tendrá 2 atributos privados y uno estático: • Atributo privado correspondiente al vector de alumnos del grupo. • Atributo privado para almacenar el número real de alumnos matriculados en el grupo en cada momento. • Atributo estático (común para todos los objetos de la clase) o de clase para almacenar el siguiente número de matrícula a asignar. • Respecto al comportamiento o métodos de la clase: • Un constructor. • Un modificador para añadir un alumno al grupo. • Un modificador para borrar un alumno del grupo. • Un consultor para calcular la nota media del grupo completo. • Un consultor para devolver todos los datos del grupo en un String. Alfonso Jiménez
ENTRADA Y SALIDA: • Como entrada, el programa presentará un menú con las siguientes opciones: • 1.- Añadir alumno al primer grupo. • 2.- Añadir alumno al segundo grupo. • 3.- Nota media total del primer grupo. • 4.- Nota media total del segundo grupo. • 5.- Borrar alumno del grupo 1 (dada la matricula). • 6.- Borrar alumno del grupo 2 (dada la matricula). • 7.- Mostrar Grupo1. • 8.- Mostrar Grupo2. • 9.- Ver el siguiente numero de matricula. • 0.- SALIR. • Entre las que el usuario deberá elegir una, comprobándose que se trata de una opción válida. Si el usuario elige añadir algún alumno, se deberá leer las 2 notas del alumno en cuestión, comprobándose que es una nota válida (entre 0 y 10). Si se elige borrar un alumno, se deberá leer la matrícula de dicho alumno y comprobar que se trata de una matrícula válida (entre 100 y 200). Alfonso Jiménez
Como posibles salidas de información, tendremos: • Las medias aritméticas de los alumnos de los grupos. • El siguiente número de matricula a asignar. • Los datos de todos los alumnos de cada grupo, de la forma: • El listado de alumnos del grupo 1 es: • NOMBRE Matricula Nota1 Nota2 • -------------------------------------------------------------- • Para gestionar todas estas entradas y salidas, se creará una nueva clase para probar las 2 diseñadas. Será la clase ‘pruebaGrupos’ y será la que contenga el método ‘main’. Alfonso Jiménez
LISTADO DEL PROGRAMA: • Clase Alumno • class Alumno • { • // Atributos o campos privados • private double not1; • private double not2; • private int mat; • private String nombre; • // Operaciones que describen el comportamiento de la clase • // Costructor • public Alumno (String nom, double not1, double not2, int mat) • { • this.nombre=new String(nom); • this.not1=not1; • this.not2=not2; • this.mat=mat; • } • // consultores • public String elNombre () • { • return (nombre); • } Alfonso Jiménez
public double nota_1() • { • return (not1); • } • public double nota_2() • { • return (not2); • } • public int matricula() • { • return (mat); • } • public double notaMed() • { • return (not1+not2)/2; • } • public String toString() • { • return (nombre+'\t'+mat+"\t\t"+not1+'\t'+not2); • } • } // Fin de la clase Alumno Alfonso Jiménez
Clase Grupo • import nsIO.*; • class Grupo • { • static output fsal = new output(); • static input fent = new input(); • // Atributos o campos privados y de referencia • private Alumno Gr[]=new Alumno[10]; • private int numAlum; • // Atributo de clase (estatico) • static int numMat=100; • // Operaciones • // Constructor • public Grupo() • { • numAlum=0; • } Alfonso Jiménez
// modificadores public void anyadirAlum(String nom, double not1, double not2) { if (numAlum < 25) { Gr[numAlum]=new Alumno(nom,not1,not2,numMat); numAlum++; numMat++; } else fsal.writeln("No caben mas..."); } public void borrarAlum(int matric) { int i=0; boolean enc=false; while ((i<numAlum) && (!enc)) if (Gr[i].matricula() == matric) enc=true; else i++; if (i<numAlum){ for (int j=i+1; j<numAlum;j++) Gr[j-1]=Gr[j]; Gr[numAlum-1]=null; numAlum--; fsal.writeln("Elemento borrado correctamente..."); } else fsal.writeln("El elem a borrar no existe en el grupo."); } Alfonso Jiménez
// Consultores public double notaMedia() { double media=0.0; for (int i=0;i<numAlum;i++) media+=Gr[i].notaMed(); media/=numAlum; return media; } public String toString() { String s=new String(); for (int i=0; i<numAlum; i++) s+=Gr[i].toString()+'\n'; return(s); } } // Fin de la clase Grupo Alfonso Jiménez
Clase pruebaGrupos • import nsIO.*; • class pruebaGrupos • { • static output fsal = new output(); • static input fent = new input(); • static int menu(){ • int opc; • do{ • fsal.writeln(""); • fsal.writeln(""); • fsal.writeln(" == MENU DE OPCIONES - GRUPOS=="); • fsal.writeln(""); • fsal.writeln("1.- Añadir alumno al primer grupo."); • fsal.writeln("2.- Añadir alumno al segundo grupo."); • fsal.writeln("3.- Nota media total del primer grupo."); • fsal.writeln("4.- Nota media total del segundo grupo."); • fsal.writeln("5.- Borrar alumno del grupo 1 (dada la mat)."); • fsal.writeln("6.- Borrar alumno del grupo 2 (dada la mat)."); • fsal.writeln("7.- Mostrar Grupo1."); • fsal.writeln("8.- Mostrar Grupo2."); • fsal.writeln("9.- Ver el siguiente numero de matricula."); • fsal.writeln("0.- SALIR."); • fsal.writeln(""); • fsal.writeln("Elige una opcion:"); • opc=fent.readint(); • } while ((opc<0)||(opc>9)); • return opc; • } /* de menu */ Alfonso Jiménez
static double lee_nota(){ double nota; do{ fsal.writeln("Dame la nota, entre 0 y 10:"); nota=fent.readdouble(); } while ((nota < 0) || (nota > 10)); return nota; } /* de lee_nota */ static int lee_mat(){ int mat; do{ fsal.writeln("Dame la matricula, entre 100 y 1000:"); mat=fent.readint(); } while ((mat < 100) || (mat > 200)); return mat; } /* de lee_mat */ Alfonso Jiménez
public static void main (String args[]){ • int opc,mat; • String nom,S; • double not1,not2,media; • Grupo Gr1=new Grupo(); • Grupo Gr2=new Grupo(); • do{ • opc=menu(); • switch (opc){ • case 1: fsal.writeln(”Nom de un alum del grupo 1:"); • nom=fent.readline(); • not1=lee_nota(); • not2=lee_nota(); • Gr1.anyadirAlum(nom,not1,not2); • break; • case 2: fsal.writeln(”Nom de un alum del grupo 2:"); • nom=fent.readline(); • not1=lee_nota(); • not2=lee_nota(); • Gr2.anyadirAlum(nom,not1,not2); • break; • case 3: media=Gr1.notaMedia(); • fsal.writeln(”Nota media del grup 1 es:"+media); • break; • case 4: media=Gr2.notaMedia(); • fsal.writeln(”Nota media del grupo 2 es:"+media); • break; • case 5: mat=lee_mat(); • Gr1.borrarAlum(mat); • break; Alfonso Jiménez
case 6: mat=lee_mat(); Gr2.borrarAlum(mat); break; case 7: S=Gr1.toString(); fsal.writeln(”Listado del grupo 1 es:"); fsal.writeln("NOMBRE"+"\t"+"Matricula"+'\t'+"Nota1"+'\t'+"Nota2"); fsal.writeln("--------------------------------------------------------------"); fsal.writeln(S); break; case 8: S=Gr2.toString(); sal.writeln("El listado del grupo 2 es:"); fsal.writeln("NOMBRE"+"\t"+"Matricula"+'\t'+"Nota1"+'\t'+"Nota2"); fsal.writeln("--------------------------------------------------------------"); fsal.writeln(S); break; case 9: fsal.writeln("El siguiente numero de matricula es:"+Grupo.numMat); break; case 0: break; } } while (opc !=0); } /* de main */ } /* de la clase */ Alfonso Jiménez