Vous êtes sur la page 1sur 17

METODO, PARAMETRO POR VALOR Y PARAMETRO POR REFERENCIA

PROGRAMACION ORIENTADA A OBJETOS


05 DE OCTUBRE DE 2011 INSTITUTO TECNOLOGICO DE TAPACHULA SWITMY MAYUMI ALVAREZ RUIZ

METODO
Un mtodo es: un subprograma

Un bloque de cdigo que tiene un nombre recibe unos parmetros o argumentos (opcionalmente contiene sentencias o instrucciones para realizar algo (opcionalmente) devuelve un valor de algn Tipo conocido (opcionalmente). Los mtodos son las acciones funciones o procedimientos que realiza nuestro programa; los mtodos son subrutinas que manipulan los datos definidos por una clase. CARACTERISTICAS DE LOS METODOS: 1.-Contiene una o ms declaraciones 2.-Cada mtodo tiene un nombre y este nombre se utiliza para llamar al mtodo(las palabras clave no pueden ser utilizadas como el nombre del mtodo). 3.-Debe llevar parntesis despus del nombre. 4.-El mtodo main() est reservado por java como el mtodo que inicializa la ejecucin del programa. DECLARACION DE METODOS La sintaxis global es: Tipo_Valor_devuelto nombre_mtodo ( lista_argumentos ) { bloque_de_codigo; }

y la lista de argumentos se expresa declarando el tipo y nombre de los mismos (como en las declaraciones de variables). Si hay ms de uno se separan por comas. Por ejemplo: int sumaEnteros ( int a, int b ) { int c = a + b; return c; } El mtodo se llama sumaEnteros. Recibe dos parmetros tambin enteros. Sus nombres son a y b. Devuelve un entero. En el ejemplo la clasula return se usa para finalizar el mtodo devolviendo el valor de la variable c. Un mtodo se implementa en una clase, y determina cmo tiene que actuar el objeto cuando recibe un mensaje. Cuando un objeto A necesita que el objeto B ejecute alguno de sus mtodos, el objeto A le manda un mensaje al objeto B. Al recibir el mensaje del objeto A, el objeto B ejecutar el mtodo adecuado para el mensaje recibido. Llamar a Mtodos de un Objeto Llamar a un mtodo de un objeto es similar a obtener una variable del objeto. Para llamar a un mtodo del objeto, simplemente se aade al nombre del objeto referenciado el nombre del mtodo, separados por un punto (.), y se proporcionan los argumentos del mtodo entre parntesis.

Si el mtodo no necesita argumentos, se utilizan los parntesis vacos. objetoReferenciado.nombreMtodo(listaArgumentos); o objetoReferenciado.nombreMtodo(); Veamos que significa esto en trminos de movimiento del rectngulo. Para mover rect a una nueva posicin utilizando el mtodo move() escribe esto. rect.move(15, 37); Esta sentencia Java llama al mtodo move() de rect con dos parmetros enteros, 15 y 37. Esta sentencia tiene el efecto de mover el objeto rect igual que se hizo en las sentencias anteriores en las que se moficaban directamente los valores x e y del objeto. rect.x = 15; rect.y = 37; Si se quiere mover un rectngulo diferente, uno llamado cubo, la nueva posicin se podra escribir. cubo.move(244, 47); Como se ha visto en estos ejemplos, las llamadas a mtodos se hacen directamente a un objeto especfico; el objeto especificado en la llamada al mtodo es el que responde a la instruccin. Las llamadas a mtodos tambin se conocen como mensajes. Como en la vida real, los mensajes se deben dirigir a un receptor particular. Se pueden obtener distintos resultados dependiendo del receptor de su mensaje. En el ejemplo anterior, se ha enviado el mensaje move() al objeto llamado rect para que ste mueva su posicin. Cuando se enva el mensaje move() al objeto llamado cubo, el que se mueve es cubo. Son resultados muy distintos.

Una llamada a un mtodo es una expresin (puedes ver Expresiones para ms informacin) y evala a algn valor. El valor de una llamada a un mtodo es su valor de retorno, si tiene alguno. Normalmente se asignar el valor de retorno de un mtodo a una variable o se utilizar la llamada al mtodo dentro del mbito de otra expresin o sentencia. El mtodo move() no devuelve ningn valor (est declarado como void). Sin embargo, el mtodo inside() de Rectangle si lo hace. Este mtodo toma dos coordenadas x e y, y devuelve true si este punto est dentro del rectngulo. Se puede utilizar el mtodo inside() para hacer algo especial en algn punto, como decir la posicin del ratn cuando est dentro del rectngulo. if (rect.inside(mouse.x, mouse.y)) { ... // ratn dentro del rectngulo ... } else { ... // ratn fuera del rectngulo ... } Recuerda que una llamada a un mtodo es un mensaje al objeto nombrado. En este caso, el objeto nombrado es rect. Entonces. rect.inside(mouse.x, mouse.y) le pregunta a rect si la posicin del cursor del ratn se encuentra entre las coordenadas mouse.x y mouse.y. Se podra obtener una respuesta diferente si enva el mismo mensaje a cubo. Como se explic anteriormente, el objetoReferenciado en la llamada al mtodo objetoReferenciado.metodo() debe ser una referencia a un objeto. Como se puede utilizar un nombre de variable aqu, tambin se puede utilizar en cualquier expresin que devuelva una referencia a un objeto. Recuerda que el operador new devuelve una referencia a un objeto. Por eso, se puede utilizar el valor devuelto por new para acceder a las variables del nuevo objeto. new Rectangle(0, 0, 100, 50).equals(anotherRect) La expresin new Rectangle(0, 0, 100, 50) evala a una referencia a un objeto que se refiere a un objeto Rectangle.

Entonces, como vers, se puede utilizar la notacin de punto (.) para llamar al mtodo equals() del nuevo objeto Rectangle para determinar si el rectanglo nuevo es igual al especificado en la lista de argumentos de equals(). TIPOS DE METODOS Tipos primitivos de Java y valores Llamamos tipos primitivos de un lenguaje cuando hablamos de tipos de datos ya definidos en el lenguaje y de los que se puede partir para la construccin de expresiones o tipos de compuestos. Los tipos son muy importantes en todos estos lenguajes de programacin y son fundamentales en Java que es un lenguaje que se basa mucho en los tipos. El concepto de tipo es muy natural: si veo un nmero, por ejemplo, 15.4 puedo decir en seguida el conjunto de nmeros al que pertenece, en este caso al conjunto de los nmeros reales. Si veo una operacin 4 / 5 puedo decir: 4 es de entero entero 5 es de tipo entero y / es una funcin de dos enteros y que me devuelve un nmero real. Se escribe as: / : ent x ent float Entonces, puedo decir que toda la expresin 4/5 es de tipo entero. Lo que acabamos de hacer es, ms o menos, una inferencia de tipos que es una prctica muy utilizada en informtica. Para explicarla toda se necesitara, como con los modelos por objetos, un curso entero. Los problemas no surgen con estas expresiones, que se llaman cerradas, que no tienen variables, sino con las que tienen variables. Cada lenguaje emplea una tcnica suya: algunas usan los tipos para las expresiones, otras establecen el tipo partiendo del contexto de la expresin y da un tipo en secuencia incluso por cada una de las expresiones, y los que, como Java, obligan a declarar todos los tipos de todas las variables desde el principio. Los tipos primitivos de Java son los mismos de los dems lenguajes de programacin, slo que difieren un poco en los valores y son.

boolean

es decir, valores que pueden ser verdaderos o falsos char los caracteres son de 16 bit y estn codificados en Unicode 1.1.5; en los dems lenguajes son ASCII solamente de 8 bit. byte

enteros de 8 bit con signo, es decir, nmero entre menos (dos a la sptima) y dos a la octava. short

enteros de 16 bit con signo. int

enteros de 32 bit con signo. long

enteros de 64 bit con signo. float

reales de 32 bit con coma mvil (IEEE 7541985). double

reales de 32 bit con coma mvil (IEEE 7541985). Obviamente, a partir de stos es posible definir nuevos tipos de datos que se llaman compuestos. Por ejemplo, una cadena es un vector de caracteres y es un tipo compuesto. Como vimos el la leccin precedente, en el paquete java.lang estn los contenedores para estos tipos de base, es decir, que si escribo ent, me refiero a un nmero entero, mientras que si escribo Enteger me refiero a las clases enteros.

Si uso las clases, tendr tambin una serie de atributos y mtodos tiles para trabajar con ellos. Por ejemplo, en alguans se definen las constantes MIN_VALUE y MAX_VALUE (Mnimo y mximo valor), en las clases Float y Double encontraremos las constantes NEGATIVE_INFINITY y POSITIVE_INFINITY, NaN para indicar un valor que no es vlido y el mtodo isNan() para controlar si un valor es vlido. Por ejemplo, se puede utilizar despus de una divisin para controlar que no se haya hecho una divisin por cero que resultara catastrfica. Todo esto no existe en los dems lenguajes de programacin. Ahora vamos a ver los literales de cada tipo de Java, es decir los valores constantes que cada tipo puede tener. El nico literal para referirnos a los objetos es null, se puede utilizar cada vez que nos esperamos una referencia a un objeto, null es un objeto que no se ha creado y no es vlido: no es de ningn tipo. Los literales boolean son verdaderos y falsos e indican, respectivamente, el valor cero y el valor falso. Los literales enteros son cadenas de cifras octales, decimales o exadecimales. El inicio de la constante sirve para escribir la base del nmero: un cero inicial indica base ocho, 0x o 0X indica base 16 y nada indica los decimales. Por ejemplo, el nmero 15 en base diez puede representarse como: 15 como decimal 017 como octal 0xf o 0XF como hexadecimal. Las constantes enteras que terminan por l o L se consideran long. Es mejor que terminen por L porque l se confunde fcilmente con la unidad (no se equivoca el compilador, pero s nosotros que leemos los programas) y si no acaban por una letra se consideran como ent. Si un lateral ent se escribe como un short o como un byte, ste se porta como si lo fuera. Los literales con coma mvil se escriben como nmeros decimales, con un punto opcional seguido, posiblemente, por un exponente que empieza por e, segn la prctica corriente para indicar mantisa-exponente. El nmero puede llevar detrs

una f (F) o una d (D) para indicar que es, con precisin, simple o doble, para default es doble. 35, 35. , 3.5y1, .35y2 representan el mismo nmero. El cero puede ser positivo o negativo, si los comparamos obtenemos la equivalencia. Sin embargo, es til en los clculos, pensemos en 1d/0d y 1d/0d. No es posible conceder una constante doble a una float aunque est en la serie. Si queremos hacer esta operacin, hay que hacer un cambio que se llama casting que analizaremos a continuacin. Los caracteres se ponen entre comilla como, por ejemplo, 2, y los caracteres especiales estn representados por unas secuencias, llamadas secuencias de escape. Son: \n newline, a parte \t tab \b backspace, borra a la izquierda \r return, representa el carcter especial ENVIO \f form feed \\ es el carcter backslash \ comilla \ comillas \ddd es un char que emplea el valor octal (d son cifras octales, por ejemplo \329, tienen que ser de tres o menos cifras y menores de \377), se puede dar tambin la representacin hexadecimal, siempre de cuatro cifras. Aqu ponemos en orden los caracteres citados antes con su nmero hexadecimal: \u000A, \u0009, \u0008, \u000D, \u000C, \u005C,

METODOS NORMALES VOLATILES Mtodos de Instancia Cuando se incluye un mtodo en una definicin de una clase Java sin utilizar la palabra clave static, estamos generando un mtodo de instancia. Aunque cada objeto de la clase no contiene su propia copia de un mtodo de instancia (no existen mltiples copias del mtodo en memoria), el resultado final es como si fuese as, como si cada objeto dispusiese de su propia copia del mtodo. Cuando se invoca un mtodo de instancia a travs de un objeto determinado, si este mtodo referencia a variables de instancia de la clase, en realidad se estn referenciando variables de instancia especficas del objeto especfico que se est invocando. La llamada a los mtodos de instancia en Java se realiza utilizando el nombre del objeto, el operador punto y el nombre del mtodo. miObjeto.miMetodoDeInstancia(); En C++, se puede acceder de este mismo modo o utilizando una variable puntero que apunte al objeto miPunteroAlObjetomiMetodoDeInstancia(); Los mtodos de instancia tienen acceso tanto a las variables de instancia como a las variables de clase, tanto en Java como en C++. Mtodos Estticos Cuando una funcin es incluida en una definicin de clase C++, o un mtodo e incluso en una definicin de una clase Java, y se utiliza la palabra static, se obtiene un mtodo esttico o mtodo de clase. Lo ms significativo de los mtodos de clase es que pueden ser invocados sin necesidad de que haya que instanciar ningn objeto de la clase. En Java se puede invocar un mtodo de clase utilizando el nombre de la clase, el operador punto y el nombre del mtodo. Mi Clase.miMetodoDeClase(); En C++, hay que utilizar el operador de resolucin de mbito para poder invocar a un mtodo de clase:

Mi Clase::miMetodoDeClase(); En Java, los mtodos de clase operan solamente como variables de clase; no tienen acceso a variables de instancia de la clase, a no ser que se cree un nuevo objeto y se acceda a las variables de instancia a travs de ese objeto. Si se observa el siguiente trozo de cdigo de ejemplo: class Documento extends Pagina { static int version = 10; int numero_de_capitulos; static void annade_un_capitulo() { numero_de_capitulos++; // esto no funciona } static void modifica_version( int i ) { version++; // esto si funciona } } la modificacin de la variable numero_de_capitulos no funciona porque se est violando una de las reglas de acceso al intentar acceder desde un mtodo esttico a una variable no esttica. Todas las clases que se derivan, cuando se declaran estticas, comparten la misma pgina de variables; es decir, todos los objetos que se generen comparten la misma zona de memoria. Los mtodos estticos se usan para acceder solamente a variables estticas. class Una Clase { int var; Una Clase() { var = 5; } unMetodo() { var += 5; } } En el cdigo anterior, si se llama al mtodo unMetodo() a travs de un puntero a funcin, no se podra acceder a var, porque al utilizar un puntero a funcin no se

pasa implcitamente el puntero al propio objeto (this). Sin embargo, s se podra acceder a var si fuese esttica, porque siempre estara en la misma posicin de memoria para todos los objetos que se creasen de la clase Una Clase.

PARAMETRO POR VALOR Y PARAMETRO POR REFERENCIA


Paso por valor significa que cuando un argumento se pasa a una funcin, la funcin recibe una copia del valor original. Por lo tanto, si la funcin modifica el parmetro, slo la copia cambia y el valor original permanece intacto. Paso por referencia significa que cuando un argumento se pasa a una funcin, la funcin recibe la direccin de memoria del valor original, no la copia del valor. Por lo tanto, si la funcin modifica el parmetro, el valor original en el cdigo que llam a la funcin cambia. Vamos a valernos de ejemplos para explicar el mecanismo con el que Java pasa parmetros a los mtodos. Tenemos el siguiente programa Java:
1 public class ValorOReferencia { 2 3 private String param1 = new String(); 4 5 /** Creates a new instance of PassValueOrReference */ 6 public ValorOReferencia(String param1) { 7 this.setParam1(param1); 8} 9 10 public static void cambiarObjeto(ValorOReferencia objeto) { 11 objeto = new ValorOReferencia("Este es un nuevo objeto."); 12 System.out.println("Luego de \"reasignar\" pass: " + objeto); 13 } 14 15 public static void cambiarParam1(ValorOReferencia objeto) { 16 objeto.setParam1("Este es un nuevo valor para param1."); 17 } 18 19 public static void main(String[] args) { 20 ValorOReferencia pass = 21 new ValorOReferencia("Objeto inicial."); 22 System.out.println("Entender que Java pasa parmetros por valor: "); 23 System.out.println("Antes de modificar pass es: " + pass); 24 ValorOReferencia.cambiarObjeto(pass); 25 System.out.println("De vuelta en main pass es: " + pass); 26 System.out.println("Ahora vamos a cambiar slo param1:"); 28 ValorOReferencia.cambiarParam1(pass); 29 System.out.println("De seguro param 1 ha cambiado: " + pass); 30 System.out.println("Parece difcil, pero no lo es.");

31 } 32 33 public String getParam1() { 34 return param1; 35 } 36 37 public void setParam1(String param1) { 38 this.param1 = param1; 39 } 40 41 public String toString() { 42 return "[param1 = " + this.getParam1() + "]"; 43 } 44 45 }

Remitmonos a lnea 20. Declaramos una variable pass, de tipo ValorOReferencia, con su nico atributo param1 inicializado con el valor Objeto inicial.. En la lnea 23, presentamos el objeto en pantalla, y se muestra el valor con el que fue declarado. Salida del programa:
Entender que Java pasa parmetros por valor: Antes de modificar pass es: [param1 = Objeto inicial.]

Ahora, en la lnea 24 pasamos nuestra variable pass al mtodo cambiarObjeto, mtodo que tiene un parmetro formal de tipo ValorOReferencia. En dicho mtodo, en la lnea 11, se realiza una asignacin
objeto = new ValorOReferencia("Este es un nuevo objeto.");

, se presenta el objeto modificado y el control regresa al mtodo main. Salida del programa:
Luego de "reasignar" pass: [param1 = Este es un nuevo objeto.]

Suponiendo que el paso de parmetros en Java fuera por referencia, la referencia pass apuntara ahora a un nuevo objeto con el valor Este es un nuevo objeto.. Pero, al regresar al mtodo main, en la lnea 25, presentamos de nuevo pass, y vemos que el valor con el que fue originalmente declarado se mantiene. Salida del programa
De vuelta en main() pass es: [param1 = Objeto inicial.]

Ahora, vamos a pasar pass y vamos a modificar solamente su nico atributo. En la lnea 28, pasamos pass al mtodo cambiarParam1, en donde tenemos la sentencia

objeto.setParam1("Este es un nuevo valor para param1.");

en la lnea 16. As, se ha modificado el valor del atributo param1, y al volver al mtodo main, presentamos pass otra vez: Salida del programa:
Ahora vamos a cambiar slo param1: De seguro param 1 ha cambiado: [param1 = Este es un nuevo valor para param1.] Parece difcil, pero no lo es.

Al ver esta ltima operacin, quiz alguien pueda decir que Java s pasa parmetros por referencia, ya que se modific el atributo del objeto, pero estara equivocado: Por qu en cambiarObjeto la variable pass no sufre ninguna modificacin, y en el mtodo cambiarParam1 su atributo se ve efectivamente modificado? Porque Java no pasa objetos como parmetros [4], sino copias de las referencias a esos objetos. Exacto. Java pasa parmetros por valor. Pasa referencias a objetos por valor. Vamos a explicar lo que cambiarObjeto(ValorOReferencia objeto) y objeto). cambiarObjeto(ValorOReferencia objeto) En main, declaramos una variable
ValorOReferencia pass = new ValorOReferencia("Objeto inicial.");

hacen nuestros mtodos cambiarParam1(ValorOReferencia

Se ha creado un objeto ValorOReferencia en cierta posicin de memoria y la forma de acceder a l es usar la referencia pass.

Omito los mtodos setters, getters y toString() en el diagrama porque no intervienen en la explicacin de este mtodo. Este mtodo tiene un parmetro formal ValorOReferencia objeto. Como Java pasa parmetros por valor tenemos que objeto, el parmetro formal de cambiarObjeto, es una copia de la referencia pass, es un alias, mas no es la referencia pass. Siguiente a la llamada al mtodo lo que tenemos es lo siguiente:

objeto es una copia de la referencia pass, es otra referencia que apunta al mismo lugar. Al ejecutar la sentencia
objeto = new ValorOReferencia("Este es un nuevo objeto.");

lo que hacemos de hecho es esto:

objeto, que originalmente era una copia de la referencia pass, apunta ahora a un nuevo objeto creado en otra posicin de memoria. Es por eso que de vuelta al main, el objeto apuntado por pass no ha cambiado. cambiarParam1(ValorOReferencia objeto) Desde el mtodo main pasamos a cambiarParam1 la referencia pass:

Incluyo el mtodo setter setParam1(String param1) porque interviene en esta explicacin. cambiarParam1 tiene un parmetro formal ValorOReferencia objeto, que es un alias de pass.

Al ejecutar la sentencia
objeto.setParam1("Este es un nuevo valor para param1.");

, lo que estamos haciendo es invocar al mtodo setParam1 del objeto apuntado por la referencia objeto. Es por eso que el atributo param1 del objeto referenciado por pass es efectivamente modificado. Cuando declaramos variables, por ejemplo,
ValorOReferencia valoRef = new ValorOReferencia();

, no declaramos un objeto ValorOReferencia, sino una referencia a un objeto ValorOReferencia. Java tiene punteros (referencias a objetos), pero no es posible manejarlos con la aritmtica con que se manejan en C++ [5]. No obstante, la implementacin de estos punteros es similar en ambos lenguajes:

Una sentencia Java ValorOReferencia valORef; es exactamente igual a una sentencia C++ ValorOReferencia *valORef;. Una sentencia Java valORef.cambiarParam1(Otro valor.); es exactamente igual a una sentencia C++ valORef -> cambiarParam1(Otro valor.);. [6]

Hay que tener claro entonces, que cuando se escribe una sentencia del estilo
cualquierFuncion(CualquierTipo argumento);

en Java, lo que se pasa no es un objeto, sino una copia de la referencia al objeto. Es importante no confundirnos. Java pasa objetos por referencia (pasa las referencias a los objetos), pero nunca pasa un objeto como parmetro [7], ni parmetros por referencia.

Vous aimerez peut-être aussi