You are on page 1of 13

-------------------------------------- using System; using System.Collections.Generic; using System.

Text;

class Fraccion { public Fraccion() { this.num = 0; this.den = 0; } public Fraccion(int num, int den) { this.num = num; this.den = den; }

//Variables public int num; public int den;

//Mtodos public Fraccion multiplica (Fraccion F1, Fraccion F2) { int sol_num = F1.num * F2.num; int sol_den = F1.den * F2.den; Fraccion soluc = new Fraccion(sol_num, sol_den); return soluc; } } class FraccionApp { static void Main(string[] args) { Fraccion uno = new Fraccion(1, 2); Fraccion dos = new Fraccion(3, 5); Fraccion solucion = new Fraccion();

solucion.multiplica(uno, dos); Console.WriteLine("{0}/{1}", solucion.num, solucion.den); } } --------------------------------------

En esta pgina vamos a definr una clase denominada Fraccion con dos miembros dato: el numerador y el denominador, y varias funciones miembro que realizan las operaciones entre fracciones. El lenguaje Java no tiene la caracterstica de la sobrecarga de operadores como el lenguaje C++. En este lenguaje es posible sobrecargar los operadores aritmticos, como funciones miembro o como funciones amigas (friend) para que se realicen las operaciones entre entidades definidas por el usuario tal como las pensamos o las escribimos en un papel. Por ejemplo, si a y b son dos fracciones (objetos de la clase Fraccion) podemos escribir c=a+b; para obtener la fraccin c resultado de la suma de a y b. Definiremos las operaciones en Java de un modo similar al lenguaje C, pero como en Java no existen funciones que no sean miembros de una clase, definiremos las operaciones como funciones estticas de una clase que denominamos Fraccion. fraccion1: Fraccion.java, FraccionApp1.java

Los miembros dato


Consideremos la clase que describe una fraccin que denominaremos Fraccion. Consta de dos miembros ambos enteros, el numerador num, y del denominador den.
public class Fraccion { int num; int den; //... }

Las funciones miembro


Adems de los constructores definiremos varias funciones miembro que codifican las operaciones que se realizan con fracciones: suma de dos fracciones, diferencia de dos fracciones, producto, cociente, fraccin inversa de una dada, y simplificar dos fracciones. Finalmente, redefiniremos la funcin toString para obtener una representacin en forma de texto de una fraccin.

Los constructores
Definiremos dos constructores, el constructor por defecto, que da al numerdor el valor cero, y al denominador el valor uno, y el constructor explcito.
public Fraccion() { num=0; den=1; } public Fraccion(int x, int y) { num=x; den=y; }

Suma de dos fracciones


Se tratar de definir una funcin denominada sumar, que realice las operacin de sumar dos fracciones. Por tanto, la funcin sumar tendr dos parmetros que son dos fracciones a y b, y devolver una fraccin, su declaracin ser
Fraccion sumar(Fraccion a, Fraccion b){ //... }

Para codificar la funcin plantearemos el procedimiento de sumar dos fracciones a y b, cuyos numeradores son a.num y b.num, y cuyos denominadores son a.den y b.den, respectivamente. El resultado se guarda en la fraccin c. El numerador c.num y el denominador c.den se obtienen del siguiente modo:

La suma de dos fracciones es otra fraccin c que tiene por numerador c.num.
c.num=a.num*b.den+b.num*a.den;

y por denominador c.den


c.den=a.den*b.den;

Una vez efectuada la suma, la funcin sumar devuelve la fraccin c


return c;

El cdigo completo de la funcin sumar es


Fraccion sumar(Fraccion a, Fraccion b){ Fraccion c=new Fraccion(); c.num=a.num*b.den+b.num*a.den; c.den=a.den*b.den; return c; }

Diferencia de dos fracciones


La funcin restar es semejante a la funcin sumar y no requiere ms explicacin.
Fraccion restar(Fraccion a, Fraccion b){ Fraccion c=new Fraccion(); c.num=a.num*b.den-b.num*a.den; c.den=a.den*b.den; return c; }

Producto de dos fracciones


Cuando se multiplican dos fracciones a y b, se obtiene otra fraccin c cuyo numerador es el producto de los numeradores, y cuyo denominador es el producto de sus denominadores respectivos.

Fraccion multiplicar(Fraccion a, Fraccion b){ Fraccion c=new Fraccion(); c.num=a.num*b.num; c.den=a.den*b.den; return c; }

Podemos ahorrarnos la fraccin temporal c, y escribir


Fraccion multiplicar(Fraccion a, Fraccion b){ return new Fraccion(a.num*b.num, a.den*b.den); }

Inversa de una fraccin

La funcin inversa, recibe una fraccin en su nico argumento y devuelve una fraccin cuyo numerador es el denominador de la fraccin argumento, y cuyo denominador es el numerador de dicha fraccin.

public static Fraccion inversa(Fraccion a){ return new Fraccion(a.den, a.num); }

Cociente de dos fracciones


Cuando se dividen dos fracciones a y b, se obtiene otra fraccin c cuyo numerador es el producto del numerador de la primera por del denominador de la segunda, y cuyo denominador es el producto del denominador de la primera por el numerador de la segunda.

Fraccion dividir(Fraccion a, Fraccion b){ return new Fraccion(a.num*b.den, a.den*b.num); }

La operacin divisin de dos fracciones es equivalente a multiplicar la fraccin a por la inversa de b, de este modo aprovechamos el cdigo de la funcin inversa.
Fraccion dividir(Fraccion a, Fraccion b){ return multiplicar(a, inversa(b)); }

Simplificar una fraccin


Para simplificar una fraccin primero hay que hallar el mximo comn divisor del numerador y del denominador. la funcin mcd se encarga de esta tarea. Para ello emplea el algoritmo de Euclides, cuyo funcionamiento se muestra en el siguiente ejemplo. Sea u=1260 y v=231,

En la primera iteracin, se halla el resto r de dividir el primero u entre el segundo v. Se asigna a u el divisor v, y se asigna a v el resto r. En la segunda iteraccin, se halla el resto r de dividir u entre v. Se asigna a u el divisor v, y se asigna a v el resto r. Se repite el proceso hasta que el resto r sea cero. El mximo comn divisor ser el ltimo valor de v.

1260=231*5+105 231=105*2+21 105=21*5+0 el mximo comn divisor es 21. Definimos en la clase Fraccion una funcin mcd que calcula y devuelve el mximo comn divisor del numerador y del denominador.
int mcd(){ int u=Math.abs(num); int v=Math.abs(den); if(v==0){ return u; } int r; while(v!=0){ r=u%v; u=v; v=r; } return u; }

A continuacin definimos la funcin simplificar, de modo que al aplicarlo sobre una fraccin, dicha fraccin se reduzca a la fraccin equivalente ms simple. Para ello, se divide numerador y denominador por el mximo comn divisor de ambos nmeros, y devuelve la fraccin simplificada.
Fraccion simplificar(){ int dividir=mcd(); num/=dividir; den/=dividir; return this; }

Aqu tenemos otro ejemplo del uso de la palabra reservada this. Los miembros dato cambian al dividirlos entre el mximo comn divisor y la funcin devuelve el objeto actual, this.

La funcin miembro toString


Para mostrar una fraccin podemos definir una funcin miembro denominada imprimir
public void imprimir(){ System.out.println(num+" / "+den);

Un objeto de la clase Fraccion llama a la funcin miembro imprimir para mostrar en la consola (una ventana DOS) los valores que guardan sus miembros dato, num y den, el numerador y el denominador. La funcin imprimir as definida no nos servir cuando la clase Fraccion se emplee en un contexto grfico. Ahora bien, como vamos a ver a continuacin el lenguaje Java nos proporciona una solucin a este problema. Aunque no se define explcitamente, la clase Fraccion deriva de la clase base Object (la estudiaremos en el siguiente captulo) y redefine la funcin miembro pblica toString, cuya tarea es la de dar una representacin en forma de texto de la fraccin.
public String toString(){ String texto=num+" / "+den; return texto; }

En la definicin de toString vemos que el operador + se usa para concatenar strings (el lenguaje Java convierte automticamente un dato primitivo en su representacin textual cuando se concatena con un string). Para mostar en la consola el numerador y el denominador de una fraccin (objeto de la clase Fraccion) a basta escribir
System.out.println(a);

Lo que equivale a la llamada explcita


System.out.println(a.toString());

Si queremos mostrar la fraccin a en un contexto grfico g de un applet o de un canvas escribimos


g.drawString("fraccin: "+a, 20, 30);

donde 20, 30 son las coordenadoas de la lnea base del primer carcter. Esta sentencia equivale a la llamada explcita
g.drawString("fraccin: "+a.toString(), 20, 30);

La redefinicin de la funcin toString devuelve un string un objeto de la clase String que guarda la representacin en forma de texto de los objetos de una determinada clase. De este modo, una clase que redefina toString puede emplearse en cualquier mbito.

La clase Fraccion

Ahora ponemos las funciones miembro dentro de la clase Fraccion, anteponiendo en las funciones que representan operaciones la palabra reservada static.
public class Fraccion { private int num; private int den; public Fraccion() { num=0; den=1; } public Fraccion(int x, int y) { num=x; den=y; } public static Fraccion sumar(Fraccion a, Fraccion b){ Fraccion c=new Fraccion(); c.num=a.num*b.den+b.num*a.den; c.den=a.den*b.den; return c; } public static Fraccion restar(Fraccion a, Fraccion b){ Fraccion c=new Fraccion(); c.num=a.num*b.den-b.num*a.den; c.den=a.den*b.den; return c; } public static Fraccion multiplicar(Fraccion a, Fraccion b){ return new Fraccion(a.num*b.num, a.den*b.den); } public static Fraccion inversa(Fraccion a){ return new Fraccion(a.den, a.num); } public static Fraccion dividir(Fraccion a, Fraccion b){ return multiplicar(a, inversa(b)); } private int mcd(){ int u=Math.abs(num); int v=Math.abs(den); if(v==0){ return u; } int r; while(v!=0){ r=u%v; u=v; v=r; } return u; } public Fraccion simplificar(){ int dividir=mcd(); num/=dividir; den/=dividir; return this; } public String toString(){

String texto=num+" / "+den; return texto; } }

Uso de la clase Fraccion


Como vemos en la definicin de la clase Fraccion tenemos funciones estticas y no estticas. Vamos a ver la diferencia entre las llamadas a funciones estticas y no estticas.

Crear un objeto de la clase Fraccion o una fraccin


Fraccion x=new Fraccion(2,3);

Mostrar una fraccin


System.out.println("x--> "+x);

Cuando se pone una fraccin x como argumento de la funcin println o se concatena con un string se llama automticamente a la funcin miembro toString, lo que equivale a la siguiente llamada
System.out.println("x--> "+x.toString());

Suma de dos fracciones


Fraccion x=new Fraccion(2,3); Fraccion y=new Fraccion(4,3); System.out.println("x+y= "+Fraccion.sumar(x, y));

Producto de dos fracciones


Fraccion x=new Fraccion(2,3); Fraccion y=new Fraccion(4,3); System.out.println("x*y= "+Fraccion.multiplicar(x, y));

Operaciones combinadas

Primero suma las fracicones x e y y luego hace el producto con la fraccin z


Fraccion x=new Fraccion(2,3); Fraccion y=new Fraccion(4,3); Fraccion z=new Fraccion(1,2); Fraccion resultado=Fraccion.multiplicar(Fraccion.sumar(x,y),z); System.out.println("(x+y)*z= "+resultado);

Simplificar una fraccin

System.out.println(resultado.simplificar());

Modificadores de acceso
Este ejemplo ilustra una faceta importante de los lenguajes de Programacin Orientada a Objetos denominada encapsulacin. El acceso a los miembros de una clase est controlado. Para usar una clase, solamente necesitamos saber que funciones miembro se pueden llamar y a qu datos podemos acceder, no necesitamos saber como est hecha la clase, como son sus detalles internos. Una vez que la clase est depurada y probada, la clase es como una caja negra. Los objetos de dicha clase guardan unos datos, y estn caracterizados por una determinada conducta. Este ocultamiento de la informacin niega a la entidades exteriores el acceso a los miembros privados de un objeto. De este modo, las entidades exteriores acceden a los datos de una manera controlada a travs de algunas funciones miembro. Para acceder a un miembro pblico (dato o funcin) basta escribir.
objeto_de_la_clase_Fraccion.miembro_pblico_no_esttico clase_Fraccion.miembro_pblico_esttico

Delante de los miembros dato, como podemos ver en el listado hemos puesto las plabras reservadas public y private.

Miembros pblicos

Los miembros pblicos son aquellos que tienen delante la palabra public, y se puede acceder a ellos sin ninguna restriccin.

Miembros privados

Los miembros privados son aquellos que tienen delante la palabra private, y se puede acceder a ellos solamente dentro del mbito de la clase. Los miembros dato num y den son privados, y tambin la funcin que calcula el mximo comn divisor mcd, que es una funcin auxiliar de la funcin miembro publica simplificar. El usuario solamente precisa saber que dispone de una funcin pblica que le permite simplificar una fraccin, pero no necesita saber cul es el procedimiento empleado para simplificar fracciones. As declaramos la funcin mcd como privada y simplificar como pblica.

Por defecto (a nivel de paquete)

Cuando no se pone ningn modificador de acceso delante de los miembros, se dice que son accesibles dentro del mismo paquete (package). Esto es lo que hemos hecho en los ejemplos estudiados hasta esta seccin.

package es la primera sentencia que se pone en un archivo .java. El nombre del paquete es el mismo que el nombre del subdirectorio que contiene los archivos .java. Cada archivo .java contiene habitualmente una clase. Si tiene ms de una solamente una de ellas es pblica. El nombre de dicha clase coincide con el nombre del archivo. Como el lector se habr dado cuenta hay una correspondencia entre archivos y clases, entre paquetes y subdirectorios. El Entorno Integrado de Desarrollo (IDE) en el que creamos los programas facilita esta tarea sin que el usuario se aperciba de ello.

Mejora de la clase Lista


list1: Lista.java, ListaApp1.java Veamos un ejemplo ms, la clase Lista, y hagamos uso de la funcin miembro ordenar para hallar el valorMenor y el valorMayor. Si tenemos una lista ordenada en orden creciente, el valor menor es el primer elemento de la lista x[0], y el valor mayor es el ltimo elemento de la lista x[n-1]. Podemos escribir el siguiente cdigo
public int valorMayor(){ ordenar(); return x[n-1]; } public int valorMenor(){ ordenar(); return x[0]; }

Podemos llamar una sla vez a la funcin miembro ordenar en el constructor, despus de haber creado el array, y evitar as la reiteracin de llamadas a dicha funcin en valorMayor, valorMenor e imprimir.
public Lista(int[] x) { this.x=x; n=x.length; ordenar(); } public int valorMayor(){ return x[n-1]; } public int valorMenor(){ return x[0]; }

La funcin miembro ordenar, es una funcin auxiliar de las otras funciones miembro pblicas, por tanto, podemos ponerle delante el modificador de acceso private. El usuario solamente est interesado en el valor medio, el valor mayor y menor de un conjunto de

datos, pero no est interesado en el procedimiento que permite ordenar el conjunto de datos. Como ocurre en la vida moderna usamos muchos aparatos pero no tenemos por que conocer sus detalles internos y cmo funcionan por dentro. Una clase es como uno de estos aparatos modernos, el usuario solamente tiene que conocer qu hace la clase, a qu miembros tiene acceso, pero no como est implementada en software.

La funcin miembro toString


Si los miembros dato de la clase Lista son privados (private) hemos de definir una funcin que hemos denominado imprimir para mostrar los valores que guardan los miembros dato de los objetos de la clase Lista.
public class Lista { private int[] x; //array de datos private int n; //dimensin //... public void imprimir(){ for(int i=0; i<n; i++){ System.out.print("\t"+x[i]); } System.out.println(""); }

La llamada a esta funcin miembro se efecta desde un objeto de la clase Lista


Lista lista=new Lista(new int[]{60, -4, 23, 12, -16}); System.out.println("Mostrar la lista"); lista.imprimir();

Sustitumos la funcin miembro imprimir por la redefinicin de toString. Para redefinir una funcin, tiene que tener el mismo nombre, los mismos modificadores, el mismo tipo de retorno y los mismos parmetros y del mismo tipo en la clase base y en la clase derivada. Para evitar errores, el mejor procedimiento es el de ir al cdigo de la clase base Object, copiar la lnea de la declaracin de toString, pegarla en la definicin de nuestra clase, y a continuacin definir dicha funcin.
public class Lista { private int[] x; //array de datos private int n; //dimensin //... public String toString(){ String texto=""; for(int i=0; i<n; i++){ texto+="\t"+x[i]; } return texto; }

La llamada a la funcin toString se realiza implcitamente en el argumento de la funcin System.out.println, o bien, al concatenar un string y un objeto de la clase Lista.
Lista lista=new Lista(new int[]{60, -4, 23, 12, -16}); System.out.println("Mostrar la lista"); System.out.println(lista); public class Lista { private int[] x; //array de datos private int n; //dimensin public Lista(int[] x) { this.x=x; n=x.length; ordenar(); } public double valorMedio(){ int suma=0; for(int i=0; i<n; i++){ suma+=x[i]; } return (double)suma/n; } public int valorMayor(){ return x[n-1]; } public int valorMenor(){ return x[0]; } private void ordenar(){ int aux; for(int i=0; i<n-1; i++){ for(int j=i+1; j<n; j++){ if(x[i]>x[j]){ aux=x[j]; x[j]=x[i]; x[i]=aux; } } } } public String toString(){ String texto=""; for(int i=0; i<n; i++){ texto+="\t"+x[i]; } return texto; } }

You might also like