Descargar como pdf o txt
Descargar como pdf o txt
Está en la página 1de 31

4

Clase , objetos
y mtodos
Conceptos fundamentales:
Aspectos esenciales de una clase.
Crear objetos.
Asignar variables de referencia.
Crear mtodos, devolver valores y usar parmetros.
Usar la palabra clave ret urn.
Devolver un valor desde un mtodo.
Aadir parmetros a un mtodo.
Utilizar constructores.
Crear constructores con parmetros.
Comprender new.
Recoleccin de elementos sin usar y finalizadores.
Usar la palabra clave thi s .
Antes a adentramos en el estudio de Java, aprenderemos el concepto de clase. Es la
esencia de Java, la base sobre la que se construye el lenguaje, ya que define la naturaleza
de los objetos. Como tal, la clase es la base de la programacin orientada a objetos en Java.
En una clase se definen datos y cdigo que acta sobre dichos datos. El cdigo se incluye
lf.jl 4. Clases, objetos y mtodos
en mtodos. Como las clases, objetos y mtodos son fundamentales en Java, los veremos
en este captulo. Si comprende estas funciones podr crear programas ms sofisticados
y entender otros elementos bsicos de Java que veremos en el siguiente captulo.
Clases: aspectos esenciales
Como toda la actividad de un programa de Java se produce en una clase, hemos
usado clases desde el principio del libro. Evidentemente, slo hemos usado clases muy
simples y no hemos aprovechado todas sus funciones. Como comprobar, las clases son
ms potentes de lo que ha visto hasta ahora.
Comenzaremos con los aspectos esenciales. Una clase es una plantilla que define la
forma de un objeto. Especifica los datos y el cdigo que acta sobre ellos. Java usa una
especificacin de clase para crear objetos, que son instancias de una clase. Por tanto,
una clase es bsicamente un conjunto de planos que especifican cmo crear un objeto.
Conviene recordar que una clase es una abstraccin lgica. Hasta que no se crea un objeto
de esa clase, no existe una representacin fsica de la misma en memoria.
Formato general de una clase
Al definir una clase, se declara su forma y naturaleza exactas. Para ello, se especi-
fican las variables de instancia que contiene y los mtodos que pueden actuar sobre
ellas. Aunque las clases muy simples pueden contener slo mtodos o slo variables de
instancia, la mayora de clases reales contiene ambos elementos.
Una clase se crea por medio de la palabra clave clas s. Veamos una forma general
simplificada de una definicin de clase:
class nombredeclase {
11 declarar variables de instancia
tipo varl ;
tipo var2 ;
11 ...
tipo varN;
11 declarar mtodos
tipo mtodol(parmetros)
11 cuerpo del mtodo
tipo mtodo2(parmetros)
11 cuerpo del mtodo
}
11
tipo mtodoN(parmetros)
11 cuerpo del mtodo
Java 7 lf.fj
Aunque no existe una regla sintctica que lo exija, una clase bien diseada debe definir
una sola entidad lgica. Por ejemplo, una clase que almacene nombres y nmeros de
telfono no almacenar informacin burstil, meteorolgica ni de otro tipo sin relacin.
Una clase bien diseada agrupa informacin vinculada de forma lgica. Si incluye infor-
macin no relacionada, puede afectar a la estructura de su cdigo. Hasta ahora, hemos
usado clases con un solo mtodo: ma i n ().Aprenderemos a crear otros. Sin embargo, el
formato general de una clase no especifica un mtodo main () . Un mtodo main () slo
es necesario si la clase es el punto de partida de un programa. Adems, algunos tipos de
aplicaciones de Java, corno los applet, no requieren main ().
Definir una clase
Para ilustrar el uso de clases, desarrollaremos una que contenga informacin sobre
vehculos, corno coches, furgonetas y camiones. El nombre de la clase es Vehicle y
almacenar tres fragmentos de informacin sobre un vehculo: el nmero de pasajeros
que admite, la capacidad del depsito y su consumo medio (en millas por galn).
Veamos la primera versin de Ve hiel e. Define tres variables de instancia:
passengers, fuelcap y mpg. Ve'."licle no contiene mtodos, por lo que es una clase
de slo datos. (Aadiremos mtodos en apartados posteriores.)
class Vehi c l e {
int passenger s ; // nmero de pasajer os
i nt fue l c ap; // c apacidad de combustible en galones
i nt mpg ; // consumo de combus tible en millas por galn
Una definicin de clase crea un nuevo tipo de datos. En este caso, es Vehicle.
Usaremos este nombre para declarar objetos de tipo Vehicle. Recuerde que una decla-
racin de clase es slo una descripcin de tipo; no crea un objeto. Por tanto, el cdigo
anterior no crea objetos de tipo Vehicle.
Para crear un objeto Vehicle, use la siguiente instruccin:
Vehicle minivan = new Vehicle( ); //cr e ar un objeto Vehicle con el nombre mi nivan
Tras ejecutar esta instruccin, mini van ser una instancia de Vehicle y tendr una
realidad fsica. Por el momento, no se preocupe de los detalles de esta instruccin.
Siempre que cree una instancia de una clase, se crea un objeto que contiene su propia
copia de cada variable de instancia creada en la clase. Por tanto, todos los objetos Vehicle
tendrn sus propias copias de las variables de instancia passengers, f uelcap y
mpg. Para acceder a estas variables, debe usar el operador de punto (.),que vincula el
nombre de un objeto al nombre de un miembro. El formato general de este operador es
el siguiente:
objeto .miembro
As pues, el objeto se especifica a la izquierda y el miembro a la derecha. Por ejemplo,
para asignar a la variable fuelcap de mi ni van el valor 16, use la siguiente instruccin:
mi niva n . fue lcap = 16 ;
4. Clases, objetos y mtodos
Por lo general, puede usar el operador de punto para acceder a variables de instancia
y a mtodos.
Veamos un programa completo que usa la clase Vehi cle:
/* Un programa que usa la clase Vehicle.
Asignar el nombre VehicleDemo . java a este archivo
*/
class Vehicle {
int passengers ; // nmero de pasajeros
int fuelcap; // capacidad de combustible en galones
int mpg; // consumo de combustible en millas por galn
11 Esta clase declara un objeto de tipo Vehicle.
class VehicleDemo {
public static void main(String args[])
Vehicle minivan = new Vehicle() ;
int range;
11 asignar valores a los campos de minivan
minivan.passengers = 7; //Uso del operador de punto para acceder a un miembro.
minivan.fuelcap = 16;
minivan.mpg = 21;
11 calcular la autonoma asumiendo que el depsito est lleno
range = minivan . fuelcap * minivan.mpg;
System. out.println( '' Minivan can carry" + minivan.passengers +
" with a range of " + range);
Debe asignar el nombre VehicleDemo. java al archivo que contenga el programa, ya
que el mtodo main () se encuentra en la clase VehicleDemo, no en la clase Vehicle.
Al compilar el programa, comprobar que se han creado dos archivos . class, uno
para Vehicle y otro para VehicleDemo. El compilador de Java incluye automtica-
mente cada clase en su propio archivo . class. No es necesario que Vehicle y la clase
VehicleDemo se encuentren en el mismo archivo fuente, puede incluirlos en archivos
independientes, corno Vehicle. java y VehicleDemo. java, respectivamente.
Para ejecutar este programa, debe ejecutar VehicleDemo . class. Obtendr el
siguiente resultado:
Minivan can carry 7 with a range of 336
Antes de continuar, repasemos un principio fundamental: cada objeto tiene sus propias
copias de las variables de instancia definidas por su clase. Por ello, los contenidos de
las variables de un objeto pueden diferir de los contenidos de las variables de otro. No
existe conexin entre los dos objetos, aparte de ser del mismo tipo. Por ejemplo, si tiene
dos objetos Vehicle, cada uno tiene su propia copia de passengers, fuel cap y mpg,
cuyos contenidos pueden variar entre los dos objetos. El siguiente programa ilustra este
hecho. (La clase con main () es ahora TwoVehicles.)
// Este programa crea dos objetos Vehicle.
class Vehicle {
int passengers; // nmero de pasajeros
int fuelcap ; // capacidad de combustible en galones
int mpg; // consumo de combustible en millas por galn
// Esta clase declara un objeto de tipo Vehicle .
class TwoVehicles {
public static void main(String args[))
Java 7 lfJI
Vehicle minivan = new Vehicle(); 11 Se refieren a objetos diferentes.
Vehicle sportscar = new Vehicle();
int rangel, range2 ;
// asignar valores a los campos de minivan
minivan.passengers = 7;
minivan.fuelcap = 16;
minivan.mpg = 21;
// asignar valores a los campos de sportscar
sportscar.passengers = 2;
sportscar.fuelcap = 14;
sportscar.mpg = 12;
// calcular la autonoma asumiendo que el depsito est lleno
rangel minivan.fuelcap * minivan.mpg;
range2 = sportscar.fuelcap * sportscar.mpg;
System. out.println("Minivan can carry " + minivan.passengers +
" with a range of " + rangel);
System.out.println( " Sportscar can carry " + sportscar.passengers +
" with a range of " + range2);
Este programa genera el siguiente resultado:
Minivan can carry 7 with a range of 336
Sportscar can carry 2 with a range of 168
Como puede apreciar, los datos de mini van son totalmente distintos a los de
sporstcar (vase la figura 4.1).
mini van

passengers
7
fuelcap
16
mpg
21
sportscar
passengers
2
fuelcap
14
mpg
12
Figura 4.1 . Diferencia entre los datos de dos objetos.
IH:I 4. Clases, objetos y mtodos
Crear objetos
En los programas anteriores, se usaba la siguiente lnea para declarar un objeto de
tipo Vehicle:
Vehicle minivan = new Vehicle();
Esta declaracin realiza dos funciones. Por un lado, declara la variable mini van del
tipo de clase Vehicle. Esta variable no define un objeto, simplemente puede hacer refe-
rencia a un objeto. Por otra parte, la declaracin crea una copia fsica del objeto y asigna
a mini van una referencia al mismo. Para ello se utiliza el operador new.
El operador new asigna dinmicamente (es decir, en tiempo de ejecucin) memoria
para un objeto y devuelve una referencia al mismo. Esta referencia es, ms o menos, la
direccin en memoria del objeto asignado por new, que despus se almacena en una
variable. As pues, en Java todos los objetos de clase deben asignarse de forma din-
mica. Los dos pasos combinados en la instruccin anterior se pueden reescribir de esta
forma:
Vehicle minivan; / / declarar referencia al objeto
minivan = new Vehicle(); //asignar un objeto Vehicle
La primera lnea declara mini van como referencia a un objeto de tipo Vehicle.
Por tanto, mini van es una variable que puede hacer referencia a un objeto, pero no es
un objeto. Todava no hace referencia a ningn objeto. La siguiente lnea crea un nuevo
objeto Vehicle y asigna a mini van una referencia al mismo. Ahora mini van est
vinculada a un objeto.
Variables de referencia y asignacin
En una operacin de asignacin, las variables de referencia de objetos actan de
forma distinta a las variables de un tipo primitivo como int. Al asignar una variable de
tipo primitivo a otra, el proceso es sencillo. La variable de la izquierda recibe una copia
del valor de la variable de la derecha. Al asignar una variable de referencia de objeto a
otra, la situacin es ms complicada, ya que se cambia el objeto al que hace referencia la
variable. El efecto de esta diferencia puede producir resultados inesperados. Por ejemplo,
fjese en este fragmento de cdigo:
Vehicle carl new Vehicle() ;
Vehicle car2 = carl;
A primera vista, se puede pensar que car 1 y car2 hacen referencia a objetos distintos
pero no es as. Ambos hacen referencia al mismo objeto. La asignacin de carl a car2
hace que car2 haga referencia al mismo objeto que car l. Por tanto, el objeto se puede
modificar desde carl o car2. Por ejemplo, tras ejecutar la asignacin
carl.mpg = 26;
estas dos instrucciones println ()
System. out . println(carl . mpg) ;
System.out . println(car2 . mpg);
muestran el mismo valor: 2 6.
Java 7 lf.;!I
Aunque carl y car2 hagan referencia al mismo objeto, no estn vinculados de otra
forma. Por ejemplo, una nueva asignacin de car2 cambia el objeto al que hace refe-
rencia:
Vehicle carl new Vehicle() ;
Vehicle car2 carl ;
Vehicl e car3 new Vehi cle ();
car2 = car3 ; // ahora car2 y car3 hacen r efer e ncia al mismo objeto .
Tras ejecutar esta secuencia, car2 hace referencia al mismo objeto que car3 y el
objeto al que carl hace referencia no cambia.
Mtodos
Como hemos visto, las variables de instancia y los mtodos forman una clase. Hasta
ahora, la clase Vehicle contiene datos, pero no mtodos. Aunque las clases de slo
datos son totalmente vlidas, la mayora tiene mtodos. Los mtodos son subrutinas
que manipulan los datos definidos por la clase y, en muchos casos, permiten acceder a
dichos datos. En muchos casos, otras partes de un programa interactan con una clase
a travs de sus mtodos.
Un mtodo contiene una o varias instrucciones. En cdigo de Java bien escrito, cada
mtodo realiza una sola tarea. Cada mtodo tiene un nombre, que se usa para invo-
carlo. Por lo general, puede asignar a un mtodo el nombre que desee pero recuerde que
main () se reserva para iniciar la ejecucin de un programa. Adems, no debe usar las
palabras clave de Java en nombres de mtodo.
Para indicar mtodos en el texto, en el libro se usa una convencin habitual en Java.
El mtodo muestra parntesis tras el nombre. Por ejemplo, si el nombre de un mtodo
es getval se escribir como getv al () al usar el nombre en una frase. Este formato
permite distinguir nombres de variables de nombres de mtodos en el libro.
El formato general de un mtodo es el siguiente:
tipo- dev nombre (lista- parmetros)
//cuerpo de l mtodo
tipo-dev especifica el tipo de datos que devuelve el mtodo, que puede ser cual-
quier tipo vlido, incluidos los tipos de clase que cree. Si el mtodo no devuelve valores,
su tipo de devolucin debe ser v oid. nombre especifica el nombre del mtodo y puede
ser cualquier identificador vlido menos los ya utilizados por otros elementos en el
mbito actual. lista-parmetros es una secuencia de pares de tipo e identificador
lij1i 4. Clases, objetos y mtodos
separados por comas. Los parmetros son variables que reciben el valor de los argu-
mentos pasados al mtodo al invocarlo. Si el mtodo carece de parmetros, la lista de
parmetros estar vaca.
Aadir un mtodo a la clase Vehicle
Corno hemos visto, los mtodos de una clase suelen manipular y proporcionar
acceso a los datos de la misma. Recuerde que en ejemplos anteriores, main ( ) calculaba
la autonoma de un vehculo multiplicado el consumo de gasolina por la capacidad del
depsito.
Aunque tcnicamente sea correcto, no es la forma ptima de realizar el clculo. La
mejor forma de realizarlo es usar la propia clase Vehi cle. El motivo es evidente. La
autonoma de un vehculo depende de la capacidad del depsito y del consumo de
combustible, cantidades que incluye la clase Vehi cle. Al aadir un mtodo a Vehicle
que calcule la autonoma, se mejora su estructura orientada a objetos. Para aadir un
mtodo a Veh icle, debe especificarlo en la declaracin de Vehicle. Por ejemplo, la
siguiente versin de Vehi c l e contiene el mtodo range () que muestra la autonoma
del vehculo:
11 Aadir autonoma a Vehicle .
class Vehicle {
int passengers ; // nmero de pasajeros
int fuelcap ; // capacidad de combustible en galones
int mpg ; // consumo de combustible en millas por galn
11 Mostrar la autonoma.
void range() { //El mtodo range() se incluye en la clase Vehicle.
System. out . println( " Range is '' + fuelcap * mpg) ; // fuelcap y mpg se usan
class AddMeth {
public static void main(String args[])
Vehicle minivan = new Vehicle() ;
Vehicle sportscar = new Vehicle() ;
int rangel , range2 ;
// directamente sin el operador de punto
// asignar valores a los campos de minivan
minivan.passengers = 7 ;
minivan . fuelcap = 16 ;
minivan . mpg = 21 ;
// asignar valores a los campos de sportscar
sportscar . passengers = 2;
sportscar . fuelcap = 14 ;
sportscar . mpg = 12 ;
System. out . print( "Minivan can carry " + minivan.passengers +
" . ") ;
minivan . range ( ) ; 11 mostrar autonoma de minivan
System.out . print( " Sportscar can carry " + sportscar . passengers +
11. ");
sportscar.range() ; 11 mostrar autonoma de sportscar.
Este programa genera el siguiente resultado:
Minivan can carry 7 . Range is 336
Sportscar can carry 2 . Range is 168
Java 7 1111
Analicemos los elementos principales del programa, empezando por el propio mtodo
range ().La primera lnea de ra'.1ge () es
void r ange( ) {
Declara un mtodo llamado range sin parmetros. Su tipo de devolucin es v o id,
por lo que range () no devuelve valores. La lnea termina con la llave de apertura del
cuerpo del mtodo.
El cuerpo de range () slo tiene una lnea:
System. out . println (" Range is " + fuelcap * mpg) ;
Esta instruccin muestra la autonoma del vehculo multiplicando fuelcap por
mpg. Como cada objeto de tipo Vehicle tiene su propia copia de fuel c ap y mpg, al
invocar range (),el clculo de autonoma usa las copias de estas variables del objeto
invocador.
El mtodo range () finaliza con la llave de cierre, lo que devuelve el control del
programa al invocador.
Tras ello, fjese en esta lnea de cdigo dentro de main ():
minivan . range( );
Esta instruccin invoca el mtodo range () en mini van. Es decir, invoca range ()
con respecto al objeto mini van, usando el nombre del objeto seguido del operador de
punto. Al invocar un mtodo, el control del programa se transfiere al mtodo. Cuando el
mtodo concluye, el control regresa al invocador y la ejecucin se reanuda en la siguiente
lnea de cdigo tras la invocacin.
En este caso, la invocacin de mini van . range () muestra la autonoma del vehculo
definido por sportscar. En cada invocacin de range (),se muestra la autonoma del
objeto especificado.
Dentro del mtodo range () se hace referencia directamente a las variables de
instancia fuelcap y mpg, sin precederlas de un nombre de objeto ni del operador de
punto. Cuando un mtodo usa una variable de instancia definida por su clase, lo hace
lltl 4. Clases, objetos y mtodos
directamente, sin hacer referencia de forma explcita a un objeto y sin usar el operador
de punto. Es fcil si lo piensa. Un mtodo siempre se invoca con respecto a un objeto de
su clase. Una vez realizada la invocacin, el objeto se conoce. Por tanto, en un mtodo,
no es necesario especificar el objeto por segunda vez. Esto significa que fuel c ap y mp g
dentro de range () hacen referencia implcitamente a las copias de dichas variables en
el objeto que invoca range ().
Devolver valores desde un mtodo
Por lo general, hay dos condiciones para que un mtodo devuelva valores. Por un
lado, como en el mtodo r ange ( ) anterior, al aparecer la llave de cierre del mtodo. La
segunda es al ejecutar una instruccin return. ret u rn tiene dos formas: una para usar en
mtodos void (los que no devuelven valores) y otra para los que devuelven valores. Aqu
veremos la primera y abordaremos la segunda en el siguiente apartado. En un mtodo
void, puede terminar inmediatamente un mtodo si usa esta forma de return:
return ;
Al ejecutar esta instruccin, el control del programa vuelve al invocador y se ignora
el cdigo restante de ese mtodo. Veamos un ejemplo:
void myMeth ()
int i ;
for (i=O ; i<lO; i++) {
if(i == 5) return; / / detenerse en 5
System.out . println() ;
Aqu, el bucle f o r slo se ejecuta de O a 5, ya que cuando i equivale a 5, el mtodo
regresa. Puede haber varias instrucciones return en un mtodo, en especial si hay dos
o ms direcciones en el mismo. Por ejemplo:
void myMeth( ) {
11 . ..
if(done) return;
11 ...
if(error ) return;
11 .. .
El mtodo regresa si termina o si se produce un error. No obstante, tenga cuidado,
ya que la presencia de demasiados puntos de salida de un mtodo puede afectar nega-
tivamente a la estructura del cdigo. Un mtodo bien diseado tiene puntos de salida
correctamente definidos.
Para resumir: un mtodo void puede regresar de dos formas: al llegar a la llave de
cierre o al ejecutar una instruccin return.
Java 7 1611
Devolver un valor
Aunque los mtodos con tipo void no son extraos, muchos mtodos devuelven un
valor. De hecho, la capacidad de devolver valores es una de las principales caracters-
ticas de un mtodo. Ya hemos visto un ejemplo al usar la funcin sqrt () para obtener
una raz cuadrada.
En programacin, los valores devueltos tienen diferentes aplicaciones. En algunos
casos, como con sqrt (),el valor devuelto contiene el resultado de un clculo. En otros
casos, simplemente indica una operacin satisfactoria o fallida. Tambin pueden incluir
un cdigo de estado. Independientemente de su funcin, el uso de valores devueltos por
mtodos es un aspecto fundamental de la programacin con Java. Los mtodos devuelven
un valor a la rutina de invocacin con el siguiente formato de return:
return valor ;
v alor es el valor devuelto. Este formato de return slo se puede usar con mtodos que
tengan un tipo de devolucin que no sea voi d . Es ms, un mtodo que no sea void debe
devolver un valor mediante este formato de retu r n . Puede usar un valor devuelto para
mejorar la implementacin de range ( ).En lugar de mostrar la autonoma, un enfoque
ms indicado es que r a nge () la calcule y devuelva este valor. Una de las ventajas de
este enfoque es que puede usar el valor en otros clculos. El siguiente ejemplo modifica
r a nge () para devolver la autonoma en lugar de mostrarla:
// Usar un valor devuelto .
class Vehicle {
int passengers ; // nmero de pasajeros
int fuelcap; // capacidad de combust i ble en galones
int mpg ; // consumo de combustible en millas por galn
// Devolver la autonoma.
int range ()
return mpg * fuelcap;
class RetMeth {
public static void main (String args[))
Vehicl e mini van = new Vehicle ( ) ;
Vehicle sportscar = new Vehicle() ;
int rangel , range2;
// asignar valores a los campos de minivan
minivan . passengers = 7;
minivan . fuelcap = 16;
minivan . mpg = 21 ;
11 asignar valores a los campos de sportscar
sportscar.passengers = 2;
sportscar . fuelcap = 14 ;
11!1 4. Clases, objetos y mtodos
sportscar . mpg = 12 ;
11 obtener las autonomas
rangel minivan . range(); //Asignar el valor devuelto a una variable .
range2 = sportscar . range();
System. out . println("Minivan can carry " + minivan . passengers +
" with range of " + rangel +"Miles");
System.out . println( "Sportscar can carry " + sportscar . passengers +
" with range of " + range2 + " miles " ) ;
Veamos el resultado:
Minivan can carry 7 with range of 336 Miles
Sportscar can carry 2 with range of 168 miles
En el programa, al invocar r ange ( ) se ubica en la parte derecha de la instruccin
de asignacin. A la izquierda se encuentra la variable que recibir el valor devuelto por
range ().Por tanto, tras ejecutar
rangel = minivan.range();
la autonoma del objeto mini van se almacena en rangel.
range () tiene ahora el tipo de devolucin int, lo que significa que devuelve un
valor entero al invocador. El tipo de devolucin de un mtodo es importante ya que el
tipo de los datos devueltos por el mtodo debe coincidir con el tipo de devolucin que
especifica. Por ello, si quiere que un mtodo devuelva datos de tipos double, su tipo de
devolucin debe ser de tipo double. Aunque el programa anterior es correcto, puede
mejorarse. En concreto, no se necesitan las variables rangel y range2. Se podra usar
directamente una invocacin de range () en la instruccin println ():
System. out.println( " Minivan can carry " + minivan.passengers +
" wi th range of " + mini van . range () + " Miles ") ;
En este caso, al ejecutar pr intln (),se invoca automticamente mini van . range ()
ysu valor se pasa aprintln () . Es ms, puede usar una invocacin de range () siempre
que necesite la autonoma de un objeto Vehicle. Por ejemplo, la siguiente instruccin
compara la autonoma de dos vehculos:
if(vl.range() > v2.range()) System. out.println ("vl has greater range" );
Utilizar parmetros
Puede pasar uno o ms valores a un mtodo al invocarlo. Recuerde que un valor
pasado a un mtodo se denomina argumento. Dentro del mtodo, la variable que recibe
el argumento se denomina parmetro. Los parmetros se declaran entre los parntesis
Java 7 ll!lj
que aparecen tras el nombre del nombre. La sintaxis de declaracin de parmetros es la
misma que la usada con variables. Un parmetro se encuentra en el mbito de su mtodo
y, aparte de recibir un argumento, acta como cualquier otra variable local.
Veamos un sencillo ejemplo que usa un parmetro. En la clase ChkNum, el mtodo
i s Even () devuelve t r u e si el valor pasado es par o false en caso contrario. Por tanto,
el tipo de devolucin de isEv e n () es boolean.
// Un sencillo ejemplo de uso de un parmetro .
class ChkNum {
// devolver true si x es par
boolean isEven(int x) { //x es un parmetro entero de isEven().
if((x%2) == 0) return true;
else return false ;
class ParmDemo {
public static void main(String args[]) {
ChkNum e= new ChkNum();
if(e.isEven(lO)) System. out.println( " lO is even ." ) ; //Pasar argumentos a isEven().
if(e . isEven(9)) System.out.println( " 9 is even ." );
if(e . isEven(8)) System. out.println( " B is even. " );
Este programa genera el siguiente resultado:
10 is even .
8 is even .
En el programa, se invoca isEv en () en tres ocasiones y cada vez se pasa un valor
diferente. Analicemos este proceso. Primero, fjese en la invocacin de isEven ( ). El
argumento se especifica entre los parntesis. Al invocar isEv e n () por primera vez, se le
pasa el valor 1 O. Por tanto, al iniciar la ejecucin de i s Ev en () ,el parmetro x recibe el
valor 1 O. En la segunda invocacin, 9 es el argumento y x tiene el valor 9. En la tercera,
el argumento es 8, el valor que recibe x. Por tanto, el valor pasado como argumento al
invocar i sEven () es el valor que recibe su parmetro x.
Un mtodo puede tener ms de un parmetro. Basta con declarar cada parmetro
separados por comas. Por ejemplo, la clase Fac t or define el mtodo is Fact or ( ) que
determina si el primer parmetro es un factor del segundo.
class Factor {
boolean isFactor(int a , int b) {
if( (b % a) == 0) return true ;
else return false;
class IsFact {
llt:I 4. Clases, objetos y mtodos
public static void main(String args[]) {
Factor x = new Factor();
if(x. isFactor (2 , 20)) System. out . println( " 2 is factor " ) ; // Pasar dos
11 argumentos a isFactor() .
i f (x . isFactor ( 3, 20)) System. out . println( " this won ' t be displayed" );
Al invocar i s Facto r (),los argumentos tambin se separan con comas.
Al usar varios parmetros, cada uno especifica su propio tipo, que puede ser diferente
del reto. Por ejemplo, lo siguiente es totalmente vlido:
int myMeth(int a , double b , float c) {
/ / .. .
Aadir un mtodo con parmetros a Vehicle
Puede usar un mtodo con parmetros para aadir nuevas funciones a la clase
Vehi c le; la posibilidad de calcular la cantidad de combustible necesaria para una
determinada distancia. Este nuevo mtodo ser fuelnee ded ();acepta el nmero de
millas que recorrer y devuelve los galones de gasolina que necesita. Veamos la defini-
cin del mtodo:
double fuelneeded(int miles) {
return (double) miles / mpg ;
El mtodo devuelve un valor de tipo d oubl e , muy til, ya que la cantidad de gaso-
lina nt::cesaria para una determinada distancia puede que no sea un nmero entero. A
continuacin se muestra la clase Vehi cle completa con el mtodo fuelneeded ( ):
/*
*/
Aadir un mtodo con parmetros que calcule el
combustible necesario para una determinada distancia.
class Vehicle {
int passengers ; // nmero de pasajeros
int fuelcap ; // capacidad de combustible en galones
int mpg; // consumo de combustible en millas por galn
11 Devolver la autonoma .
int range ()
return mpg * fuelcap;
// Calcular el combustible necesario para una determinada distancia .
double fuelneeded(int miles)
return (double) miles / mpg;
class CompFuel {
public static void main(String args[))
Vehicle mini van = new Vehicle();
Vehicle sportscar = new Vehicle() ;
double gallons ;
int dist = 252;
11 asignar valores a los campos de minivan
minivan . passengers = 7;
minivan . fuelcap = 16;
minivan.mpg = 21 ;
11 asignar valores a los campos de sportscar
sportscar . passengers = 2 ;
sportscar . fuelcap = 14;
sportscar . mpg = 12 ;
gallons = minivan.fuelneeded(di st );
System.out . println( " To go " + dist + " miles minivan needs " +
gallons + " gallons of fuel . ") ;
gallons = sportscar.fuelneeded(dist) ;
System.out . println( " To go " + dist + " miles sportscar needs " +
gallons + " gallons of fuel ." ) ;
Este programa genera el siguiente resultado:
Togo 252 miles minivan needs 12 . 0 gallons of fuel.
Togo 252 miles sportscar needs 21 . 0 gallons of fuel .
Java 7 llfl
Si intentaremos resumir la esencia de una clase en una frase podramos decir una clase
encapsula funcionalidad. Evidentemente, en ocasiones hay que saber dnde acaba una
funcionalidad y empieza otra. Por lo general, las clases deben ser piezas para crear apli-
caciones de mayor tamao. Para ello, cada clase debe representar una unidad funcional
que realice acciones claramente definidas. Por lo tanto, las clases deben ser de tamao
reducido pero no demasiado. Es decir, las clases que contienen demasiada funcionalidad
confunden y desestructuran el cdigo pero las clases que apenas contienen funcionalidad
se fragmentan. El equilibrio? Aqu es donde la ciencia de la programacin se convierte
en arte. Afortunadamente, muchos programadores descubren que el arte se alcanza con
la experiencia.
Para empezar a adquirir dicha experiencia, convertiremos el sistema de ayuda del
ejercicio 3.3 en una clase de ayuda. Veamos por qu es una buena idea. Por un lado, el
sistema de ayuda define una unidad lgica. Por otro, incluir ayuda en una clase es un
11
iij:I 4. Clases, objetos y mtodos
enfoque estticamente atractivo. Siempre que desee ofrecer el sistema de ayuda a un
usuario, basta con crear una instancia del objeto del sistema de ayuda. Por ltimo, como
la ayuda est encapsulada, se puede actualizar o modificar sin efectos secundarios no
deseados en los programas que la utilicen.
l. Cree un nuevo archivo con el nombre HelpCl assDemo . java. Para ahorrarle
trabajo, puede copiar el archivo Help3 . java del ejercicio 3.3 a HelpCl assDemo .
java.
2. Para convertir el sistema de ayuda en una clase, primero debe determinar los
elementos del mismo. Por ejemplo, en He lp3 . java, hay cdigo para mostrar
un men, introducir la eleccin del usuario, comprobar la validez de la respuesta
y mostrar informacin sobre el elemento seleccionado. El programa se ejecuta
en bucle hasta que se pulsa la tecla q. Si lo piensa, es evidente que el men, la
comprobacin de la respuesta y la informacin mostrada son partes integrales
del sistema de ayuda. Pero no la forma de obtener las entradas del usuario y si
deben procesarse las solicitudes repetidas. Por tanto, crearemos una clase que
muestre la informacin de ayuda, el men de ayuda y compruebe la validez de
las selecciones. Sus mtodos son helpon ( ), s howmenu () e isvalid () , respec-
tivamente.
3. Cree el mtodo helpon ():
void helpon(int what)
switch (what) {
case ' 1' :
System. out.println( " The if : \n" );
System. out.println( " if(condition) statement; " ) ;
System.out.println( " else statement; " );
break;
case ' 2 ' :
System. out.println( " The switch:\n" );
System. out. println ( " switch (expression) { " ) ;
System. out . println( " case constant: " ) ;
System. out . println( " statement sequence" );
System.out.println( " break; ");
System. out.println( " // .. . " ) ;
System. out . println( " }" );
break;
case ' 3 ' :
System. out . println( " The for : \n" ) ;
System. out.print( " for(init ; condition; iteration) " );
System. out.println( " statement ;" ) ;
break;
case ' 4 ' :
System. out . println( " The while:\n" );
System. out . println( " while(condition) statement ;" ) ;
break;
case ' 5':
System. out.println("The do-while:\n" );
System. out . println( " do {" ) ;
System. out . println( " statement; " );
System.out.println( " } while (condition) ;" );
break;
case ' 6 ':
System. out.println( " The break : \n" ) ;
System. out. println ( "break; or break label ; " ) ;
break;
case ' 7 ':
System. out . println( " The continue : \n" ) ;
System. out . println( " continue ; or continue label ;" );
break;
System. out . println() ;
4. Tras ello, cree el mtodo s h o wmenu () :
void showmenu() {
System. out . println( " Help
System.out . println (" l.
System. out . println( " 2 .
System.out.println( "
System. out . println( " 4.
System.out.println( "
on : " };
if" ) ;
switch" ) ;
for " ) ;
while " ) ;
do- while " ) ;
System. out . println( " 6 . break" ) ;
System. out . println( " 7 . continue\n" ) ;
System. out . print( " Choose one (q to quit) : " );
5. Cree el mtodo i svalid ():
boolean isvalid(int ch) {
if(ch < ' 1 ' 1 ch> ' 7 ' & ch != ' q ' ) return false ;
else return true;
6. Combine los mtodos en la clase He l p :
class Help {
void helpon(int what)
switch (what) {
case ' 1 ' :
System.out.println( " The if : \n");
System.out . println( " if(condition) statement ;");
System.out.println (" else statement ;" ) ;
break;
case ' 2 ':
System. out . println( " The switch : \n" );
System. out. println ( " switch (expression) {" ) ;
System. out . println( " case constant :" ) ;
System. out.println( " statement sequence" ) ;
System. out . p r intln( " break;" );
System. out . println( " // . . . " );
System.out . println( " }" ) ;
break;
case ' 3 ':
System.out . println( " The for : \n" ) ;
System.out . print( " for(init ; condition; iteration) " );
Java 7 lfijl
4. Clases, objetos y mtodos
System. out . println( " statement ;" ) ;
break;
case ' 4 ' :
System. out . println( " The while : \n" ) ;
System. out . println( " while(conjition) statement ;" ) ;
break;
case ' 5 ':
System. out . println( " The do- while : \n" ) ;
System. out . println( "do {" ) ;
System. out . println( " statement ;" ) ;
System. out . println( " } while (condition}; " ) ;
break;
case ' 6 ':
System.out . println( " The break: \n" );
System. out . println( "break; or break label ;" );
break;
case ' 7 ':
System. out . println( "The continue : \n" ) ;
System. out . println( " continue; ar continue label ;" );
break;
System. out . println() ;
void showmenu() {
System. out . println( " Help on :" ) ;
System. out.println( " l. if" ) ;
System. out . println( " 2 . switch" ) ;
System. out . println( " 3 . far " ) ;
System. out . println( " 4 . while " );
System. out . println( " 5 . do- while");
System. out . println( " 6 . break") ;
System. out . println( " 7 . continue\n" ) ;
System. out.print( " Choose one (q to c;:uit) : " ) ;
boolean isvalid(int ch) {
if (ch < ' l ' 1 ch> ' 7 ' & ch ! = ' q ') retu rn false ;
else return true ;
7. Por ltimo, modifique el mtodo rnain () del ejercicio 3.3 para que use la nueva
clase Help. Asigne el nombre HelpClassDerno . j ava a esta clase. Veamos su
cdigo completo:
/*
*/
Ejercicio 4.1
Convertir el sistema de ayuda del ejercicio 3.3
en una clase de ayuda .
class Help {
void helpon (int what)
switch (what) {
case ' l ':
System.out.println( " The if : \n" );
System.out.println("if(condition) statement; " ) ;
System.out.println( " else statement;") ;
break;
case ' 2 ':
System. out.println( " The switch:\n" ) ;
System. out . println ("switch (expression) { " ) ;
System. out . println( " case constant: ");
System. out . println( " statement sequence" );
System.out.println( " break; " ) ;
System. out . println( " // . .. " );
System. out.println( " }" );
break;
case '3':
System. out . println( " The for : \n" );
System.out.print( " for(init ; condition; iteration)");
System.out.println( " statement ;" ) ;
break;
case '4':
System.out.println (" The while:\n" );
System. out . println( " while(condition) statement; " ) ;
break;
case ' 5 ':
System.out . println( " The do- while : \n" );
System. out . println("do {" ) ;
System.out . println( " statement ;" );
System.out . println( " } while (condition); " );
break;
case ' 6 ':
System.out.println("The break : \n" );
System.out . println( "break; or break label; ");
break;
case ' 7 ':
System. out . println( "The continue:\n" );
System. out . println( " continue; or continue label;");
break;
System. out . println();
void showmenu ()
System. out . println( "Help on :" );
System. out.println( " l. if" ) ;
System. out . println( " 2 . switch" ) ;
System.out . println( " 3 . for ");
System. out . println( " 4 . while " ) ;
System.out . println( " 5 . do- while");
System. out . println( " 6. break" ) ;
System. out.println( " 7. continue\n" );
System.out.print( " Choose one (q to quit) : ");
boolean isvalid(int ch) {
if(ch < ' 1' 1 ch> ' 7 ' & ch!= ' q ' ) return false;
else return true;
Java 7 1111
lltj 4. Clases, objetos y mtodos
class HelpClassDemo {
public static void main(String args[])
throws java . io.IOException {
char choice, ignore;
Help hlpobj = new Help();
for (;;) {
do {
hlpobj . showmenu() ;
choice = (char) System.in . read();
do {
ignore = (char) System. in.read();
} while(ignore != '\n');
while( !hlpobj.isvalid(choice) I;
if(choice == ' q') break;
System.out . println( " \n" ) ;
hlpobj . helpon(choice) ;
Al probar el programa, comprobar que tiene la misma funcionalidad (vase la
figura 4.2). La ventaja de este enfoque es que ahora dispone de un componente
de sistema de ayuda que puede reutilizar siempre que lo desee.
Constructores
En los ejemplos anteriores, las variables de instancia de cada objeto Vehic le
deban establecerse manualmente por medio de una secuencia de instrucciones como
la siguiente:
minivan . passengers = 7;
minivan.fuelcap = 16;
minivan.mpg = 21;
Este enfoque nunca se usara en cdigo profesional. Adems de ser proclive a errores
(podra olvidarse de establecer uno de sus campos), existe una forma ms sencilla de
realizar esta tarea: un constructor.
Un constructor inicializa un objeto al crearlo. Tiene el mismo nombre que su clase y es
sintcticamente similar a un mtodo. Sin embargo, los constructores carecen de un tipo
de devolucin explcito. Por lo general, los constructores se usan para asignar valores
iniciales a las variables de instancia definidas por la clase, o para realizar otros procedi-
mientos de inicio necesarios para crear un objeto bien formado.
Java 7 IGSI
ili Slmbolo del sistema java HelpClassOemo
Figura 4.2. Ejemplo de un componente de sistema de ayuda.
Todas las clases tienen constructores, los defina o no, ya que Java ofrece automti-
camente un constructor predeterminado que inicializa todas las variables miembro en
sus valores predeterminados, que son cero, null y false para tipos numricos, tipos
de referencia y tipos boolean, respectivamente. No obstante, tras definir su propio cons-
tructor, el predeterminado deja de usarse.
Veamos un ejemplo que usa un constructor:
11 Un sencillo constructor .
class MyClass
int x;
MyClass ()
X = 10;
11 El constructor de MyClass .
11!1 4. Clases, objetos y mtodos
class ConsDemo {
public static void main(String args[)) {
MyClass tl new MyClass() ;
MyClass t2 = new MyClass() ;
System. out . println(tl.x + " " + t2 . x) ;
En este ejemplo, el constructor de MyClass es
MyClass () {
X = 10 ;
Este constructor asigna el valor 10 a la variable x de MyClass. Se invoca por new al
crear un objeto. Por ejemplo, en la lnea
MyClass tl = new MyClass();
el constructor MyClass () se invoca en el objeto tl y asigna el valor 10 a tl . x. Lo
mismo sucede con t 2 . Tras el constructor, t 2 . x tiene el valor 1 O. Por ello, el resultado
del programa es:
10 10
Constructores con parmetros
En el ejemplo anterior, se usaba un constructor sin parmetros. Aunque es correcto en
algunos casos, a menudo necesitar un constructor que acepte uno o varios parmetros.
En un constructor, los parmetros se aaden como a un mtodo: basta con declararlos
entre parntesis tras el nombre del constructor. En el siguiente ejemplo, se asigna un
constructor con parmetros a MyClass:
11 Un constructor con parmetros.
class MyClass
int x;
MyClass(int i) { //Este constructor tiene un parmetro.
X = i;
class ParmConsDemo {
public static void main(String args[])
MyClass tl new MyClass(lO);
MyClass t2 = new MyClass(88);
System. out.println(tl.x + " " + t2 . x);
Java 1 IGlll
Este programa genera el siguiente resultado:
10 88
En esta versin del programa, el constructor MyClas s () define el parmetro i, que
se usa para inicializar la variable de instancia x. Por tanto, al ejecutar la lnea
MyClass tl = new MyClass ( lO) ;
se pasa el valor 1 O a i, que despus se asigna a x.
Aadir un constructor a la clase Vehicle
Podernos mejorar la clase Vehi c le si aadirnos un constructor que inicialice auto-
mticamente los campos passengers, f uel c a p y mpg al construir un objeto. Fjese en
cmo se crean los objetos Vehi c le.
// Aadir un constructor .
class Vehicle {
int passengers ;
int fuelcap;
int mpg;
11 nmero de pasajeros
11 capacidad de combustible en galones
// consumo de combustible en millas por galn
// Un constructor para Vehicle.
Vehicle(int p , int f , int m) {
passengers = p ;
fuelcap = f ;
mpg = m;
// Devolver la autonoma.
int range () {
return mpg * fuelcap;
// Calcular el combustible para una determinada distancia.
double fuelneeded ( int miles) {
return (double) miles / mpg ;
class VehConsDemo {
public static void main(String args[J)
// crear vehculos completos
Vehicle minivan = new 16 , 21) ;
Vehicle sportscar = new Veh:cle(2 , 14 , 12);
double gallons ;
int dist = 252 ;
gallons = minivan . fuelneeded(dist) ;
11
1!11 4. Clases, objetos y mtodos
System. o ut .println( " To go " + dist + " miles minivan needs " +
gallons + " gallons of f uel ." ) ;
gallons = sportscar . fuelneeded(di st) ;
System.out . println( " To go " + dist + " mi l es sportscar needs " +
gallons + " gallons of fuel ." ) ;
Tanto mini v an como s p o r tscar se inicializan con el constructor Vehi cle () al
crearse. Cada objeto se inicializa en funcin de lo especificado en los parmetros de su
constructor. Por ejemplo, en la siguiente lnea
Vehicle minivan = new Vehicle(7 , 16, 21 );
los valores 7, 16 y 21 se pasan al constructor Vehi cle () cuando new crea el objeto. Por
tanto, la copia de passengers, f uelcap y mpg en mini v an contendr los valores 7,
1 6 y 21, respectivamente. El resultado de este programa es el mismo que en la versin
anterior.
Revisin del operador new
Despus de ver las clases y sus constructores, analizaremos de nuevo el operador
new. En el contexto de una asignacin, new tiene este formato general:
var- clase = new nombre- clase(lista- argumentos)
v ar-cl a s e es una variable del tipo de clase creada. n omb re-cl ase es el nombre de
la clase de la que se crea una instancia. El nombre de la clase seguido de una lista de argu-
mentos entre parntesis (que puede estar vaca) especifica el constructor de la clase. Si una
clase no define su propio constructor, new usa el predeterminado de Java. Por ello, new
se puede usar para crear un objeto de cualquier tipo de clase. El operador new devuelve
una referencia al nuevo objeto creado que, en este caso, se asigna a v ar-c l ase.
Como la memoria es limitada, puede que n ew no consiga asignar memoria para un
objeto en caso de que sea insuficiente. En este caso, se genera una excepcin de tiempo de
ejecucin, como veremos en el captulo 9. Para los ejemplos del libro, no debe preocuparse
de quedarse sin memoria, pero tenga en cuenta esta posibilidad en programas reales.
Preguntas al experto
P: Por qu no es necesario usar new en variables de tipos primitivos como int o
float?
R: Los tipos primitivos de Java no se implementan como objetos. Por motivos de efi-
cacia, se implementan como variables normales. Una variable de un tipo primitivo
Java 7 IGfl
contiene el valor que le haya asignado. Como hemos visto, las variables de objeto
son referencias al mismo. Este nivel de indireccin (y otras caractersticas de los
objetos) aade sobrecarga a un objeto que los tipos primitivos evitan.
Recolectar elementos sin usar y finalizadores
Como hemos visto, los objetos se asignan dinmicamente desde memoria libre por
medio del operador n e w. Adems, la memoria es limitada y se puede agotar. Por tanto,
new puede fallar debido a falta de memoria libre para crear el objeto deseado. Por este
motivo, un componente clave de cualquier sistema de asignacin dinmica es la recu-
peracin de memoria libre de objetos sin usar, para que est disponible en nuevas asig-
naciones. En muchos lenguajes de programacin, la liberacin de memoria previamente
asignada se controla manualmente. Por ejemplo, en C++, se usa el operador delete.
Pero Java usa otro enfoque: la recoleccin de elementos sin usar.
Este sistema reclama los objetos automticamente, de forma transparente entre basti-
dores sin intervencin del programador. Cuando no existen referencias a un objeto,
se supone que dicho objeto ya no es necesario y se libera la memoria que ocupa. Esta
memoria reciclada se puede usar en posteriores asignaciones.
La recoleccin de elementos sin usar se produce espordicamente durante la ejecu-
cin del programa. No se produce porque existan objetos que ya no se utilicen. Por
motivos de eficacia, el recolector suele ejecutarse cuando se cumplan dos condiciones:
que existan objetos que reciclar y que sea necesario reciclarlos. Recuerde que la recolec-
cin de elementos sin usar lleva su tiempo, por lo que el sistema de tiempo de ejecucin
de Java la realiza cuando es necesario.
El mtodo finalize()
Se puede definir un mtodo que invocar antes de la destruccin definitiva de un objeto
por parte del recolector de elementos sin usar: fi n a 1 i z e ( ) . Se puede usar para garan-
tizar la eliminacin de un objeto de forma limpia, por ejemplo, para cerrar un archivo
abierto propiedad del objeto.
Para aadir un finalizador a una clase, basta con definir el mtodo f i na lize ().El
sistema de tiempo de ejecucin de Java lo invoca antes de reciclar un objeto de esa clase.
Dentro del mtodo fin a 1 i z e ( ) se especifican las acciones que deben realizarse antes
de destruir un objeto.
El formato general del mtodo finalize () es el siguiente:
protected void f i nalize (
{
11 aadir aqu cdigo de finalizacin
11!:1 4. Clases, objetos y mtodos
La palabra clave protectedes un especificador que impide el acceso a fi na lize ()
por parte de cdigo definido fuera de su clase. En el captulo 6 veremos este y otros
especificadores de acceso.
Recuerde que finalize () se invoca justo antes de la recoleccin de elementos sin
usar, no cuando un objeto sale de mbito. Esto significa que no puede saber cundo se
ejecutar finalize ().Por ejemplo, si su programa termina antes de la recoleccin,
finalize () no se ejecutar. Por tanto, debe usarse como procedimiento de respaldo
para garantizar el control adecuado de un recurso o en aplicaciones especiales, no para
el funcionamiento normal de un programa. En definitiva, f inal i ze () es un mtodo
especializado que apenas es necesario en la mayora de programas.
Preguntas al experto
P: En C++ se definen elementos denominados destructores que se ejecutan autom-
ticamente al destruir un objeto. lfinali ze () es similar a un destructor?
R: Java no tiene destructores. Aunque es cierto que fina 1 i z e ( ) se aproxima a esta
figura, no es lo mismo. Por ejemplo, un destructor C++ siempre se invoca antes de
que un objeto salga de mbito pero no puede saber cundo se invoca f i nal i ze ( )
para un objeto concreto. Francamente, con la recoleccin de elementos sin usar,
no se necesitan destructores.
EjerclclO 4.a. Ejemplo de recoleccin de elementos sin usar y flnallzacln
Como la recoleccin de elementos sin usar se ejecuta espordicamente de fondo,
no es fcil de ilustrar. Sin embargo, se puede hacer por medio de finalize ( ) ,que se
invoca antes de que se recicle un objeto. Como hemos mencionado, no es necesario que
los objetos se reciclen en cuanto no son necesarios. El recolector espera hasta que pueda
realizar su funcin de forma eficaz, normalmente cuando hay mltiples objetos sin usar.
Por ello, para ilustrar la recoleccin de elementos sin usar a travs de f inal i ze (),debe
crear y destruir varios objetos, lo que haremos en este ejercicio.
l. Cree un nuevo archivo con el nombre Finalize. java.
2. Cree la siguiente clase FDemo:
class FDemo
int x ;
FDemo (int i) {
X = i ;
11 se invoca al reciclar el objeto
protected voi d finalize() {
System. out . println (" Finalizing " + x) ;
// genera un objeto que se destruye inmediatamente
void generator(int i) {
FDemo o= new FDemo(i) ;
Java 7 llQI
El constructor establece la variable de instancia x en un valor conocido. En este
ejemplo, se usa x como ID de objeto. El mtodo finalize () muestra el valor
de x al reciclar un objeto. genera tor () es de especial inters. Este mtodo crea
y descarta un objeto FDemo. Veremos cmo se usa en el siguiente paso.
3. Cree la clase Finalize:
class Finalize {
public static void main(String args[)) {
int count ;
FDemo ob = new FDemo (O);
/ * Ahora , generar numerosos objetos . En algn
momento se recolectarn los elementos sin usar .
Nota : puede que necesite aume nte el nmero
de objetos generados para forzar la recoleccin
de eleme ntos s in usar . * /
for(count=l ; count < 100000 ; count++)
ob . generator (count );
Esta clase crea un objeto FDemo inicial ob. Tras ello, con ob, crea 100.000 objetos
mediante la invocacin de genera tor () en ob. Como efecto, se crean y descartan
100.000 objetos. En distintos puntos del proceso, se realiza la recoleccin de
elementos sin usar. La frecuencia exacta depende de varios factores, como la
cantidad inicial de memoria libre y del sistema operativo. Sin embargo, en un
punto concreto, comienzan a aparecer mensajes generados por f inalize ().Si
no ve los mensajes, incremente el nmero de objetos generados aumentando el
valor count en el bucle f or.
4. Veamos el programa Finali ze. java completo:
/*
Ejercicio 4.2
Ejemplo de recoleccin de elementos sin usar y del mtodo finalize() .
*/
class FDemo
i nt x ;
FDemo (int i) {
X = i ;
l
119111 4. Clases, objetos y mtodos
11 se invoca al reciclar el objeto
protected void finalize() {
System. out . println( " Finalizing " + x) ;
11 genera un objeto que se destruye inmediatamente
void generator(int i) {
FDemo o= new FDemo(i) ;
class Finalize {
public static void main(String args[]) {
int count;
FDemo ob = new FDemo(O) ;
/* Ahora, generar numerosos objetos. En algn
momento se recolectarn los elementos sin usar.
Nota: puede que necesite aumente el nmero
de objetos generados para forzar la recoleccin
de elementos sin usar . */
for(count=l ; count < 100000; count++)
ob . generator(count);
La palabra clave this
Antes de concluir el captulo, debemos presentar t h is. Al invocar un mtodo, se le
pasa automticamente un argumento implcito que es una referencia al objeto invocador
(es decir, el objeto en el que se invoca el mtodo). Esta referencia se denomina this.
Para entenderla, veamos un programa que crea la clase Pwr que calcula el resultado de
un nmero elevado a una potencia entera:
class Pwr
double b;
int e;
double val ;
Pwr(double base, int exp) {
b base;
e = exp;
val = 1;
if(exp==O) return;
for( ; exp>O; exp--) val
double get_pwr()
val * base;
return val;
class DemoPwr {
public static void main(String args[]) {
Pwr x new Pwr(4.0, 2);
Pwr y new Pwr(2.5, l);
Pwr z = new Pwr(S.7 , 0);
Java 7 llejl
System.out.println(x . b + " raised to the " + x . e + " power is " + x.get_pwr());
System.out.println(y. b + " raised to the " + y.e + " power is " + y.get_pwr());
System.out . println(z . b + " raised to the " + z . e + " power is " + z.get_pwr());
Corno sabe, en un mtodo, se puede acceder directamente a otros miembros de una
clase sin calificacin de objetos o clases. Por tanto, dentro de get _ p wr () ,la instruc-
cin:
return val;
significa que se devuelve la copia de val asociada al objeto invocador. Sin embargo, la
misma instruccin se puede escribir de esta forma:
return this.val;
Aqu, this hace referencia al objeto en el que se invoca get_ pwr ( ).Por tanto,
this . val hace referencia a la copia de val de ese objeto. Por ejemplo, si get _ pwr ( )
se hubiera invocado en x, this habra hecho referencia a x. Crear una instruccin sin
usar t his es simplemente una abreviatura.
Veamos la clase Pwr completa con la referencia this:
class Pwr
double b;
int e ;
double val;
Pwr(double base, int exp) {
this.b base;
this . e = exp;
this . val = l;
if(exp==O) return;
for( ; exp>O; exp--) this.val
double get_pwr() {
return this.val;
this . val * base;
119fj 4. Clases, objetos y mtodos
En realidad, ningn programador de Java creara Pwr de esta forma ya que no ofrece
ventaja alguna y la forma estndar resulta ms sencilla. Sin embargo, thi s tiene impor-
tantes aplicaciones. Por ejemplo, la sintaxis de Java permite que el nombre de un par-
metro o variable local coincida con el de una variable de instancia. En ese caso, el nombre
local oculta la variable de instancia. Puede acceder a la variable de instancia oculta si hace
referencia a la misma por medio de this. Por ejemplo, aunque no sea un estilo recomen-
dable, el siguiente cdigo es sintcticamente vlido para crear el constructor Pwr ().
Pwr(double b, int e) {
this . b = b; // Hace referencia a la variable je instancia b , no al parmetro.
this.e = e ;
val = 1;
if(e==O) return ;
for( ; e>O; e--) val =val * b;
En esta versin, los nombres de los parmetros coinciden con los nombres de las
variables de instancia, por lo que se ocultan. No obstante, se usa this para revelar las
variables de instancia.
Evaluacin de conocimientos
l. Cul es la diferencia entre una clase y un objeto?
2. Cmo se define una clase?
3. De qu elemento tiene una copia propia un objeto?
4. Con dos instrucciones diferentes, indique cmo declarar el objeto counter de la
clase MyCounter.
5. Indique cmo declarar el mtodo myMeth () si tiene el tipo de devolucin double
y dos parmetros int, a y b.
6. Cmo debe devolverse un mtodo que devuelva un valor?
7. Qu nombre tiene un constructor?
8. Cul es la funcin de new?
9. Qu es la recoleccin de elementos sin usar y cmo funciona? Qu es
finalize ()?
10. Qu es this?
11. Un constructor puede tener uno o varios parmetros?
12. Si un mtodo no devuelve valores, qu tipo de devolucin debe tener?

También podría gustarte