Cap6 clases

Page 1

Capítulo 6

Las clases Síntesis del Manual de Referencia Java 2 Cuarta edición – Herbert Schildt

Fundamentos de las clases Forma general de una clase Una clase sencilla Declaración de objetos El operador new Asignación de variables de referencia a objetos Métodos Adición de un método de la clase Caja Devolución de un valor Métodos con parámetros Constructores Constructores con parámetros La palabra clave: this Recogida de basura

Instituto Tecnológico de Pachuca – Roberto Hernández Pérez. Rev. Jun 2013


Las clases

Las clases Las clases son el núcleo de Java. La construcción lógica sobre la que se basa el lenguaje Java define la forma y naturaleza del objeto y forma la base de la programación orientada a objetos en Java. Cualquier concepto que se quiera implementar en Java debe estar encapsulado dentro de una clase.

Fundamentos de las clases

Las clases creadas en los capítulos anteriores existían simplemente para encapsular el método main(), que ha permitido mostrar los fundamentos de la sintaxis de Java.

Forma general de una clase

Cuando se define una clase, se declara su forma y naturaleza exactas, especificando los datos que contiene y el código que opera sobre los mismos. Las clases más sencillas pueden contener solamente código o solamente datos, pero en la práctica, las clases contienen datos y código. El código de una clase define la interfaz con sus datos.

Una clase se declara mediante la palabra clave class. La forma general de definir una class es la siguiente:

class nombre de la clase { tipo variable de instancia1; tipo variable de instancia2; // … tipo variable de instanciaN; tipo nombre del método1(lista de parámetros) { // Cuerpo del método }

Instituto Tecnológico de Pachuca – Roberto Hernández Pérez. Rev. Jun 2013

6-2


Las clases

tipo nombre del método2(lista de parámetros) { // Cuerpo del método } // … type nombre del método N (lista de parámetros) { // Cuerpo del método } } Los datos, o variables, definidos en una clase se denominan variables de instancia. El código está contenido en los métodos. El conjunto de los métodos y las variables definidos dentro de una clase se denominan miembros de la clase. En la mayor parte de las clases, los métodos acceden y actúan sobre las variables de instancia, es decir, los métodos determinan como se deben utilizar los datos de una clase.

Todos los métodos tienen el mismo formato general que el método main(). Sin embargo, la mayor parte de los métodos no se especifican como static o public. Observe que la forma general de una clase no especifica un método main(). Las clases de Java no tienen necesariamente un método main(). Solamente se especifica un método main() si esa clase es el punto de comienzo del programa. Las applets, por ejemplo, no requieren un método main().

Una clase sencilla

Esta clase define tres variables de instancia: ancho, alto y largo. En este caso, Caja no contiene método alguno.

class Caja { double ancho; double alto; double largo; }

Una clase define un nuevo tipo de dato. En este caso, el nuevo tipo se denomina Caja. Es importante recordar que la declaración de una clase solamente crea un modelo o patrón y

Instituto Tecnológico de Pachuca – Roberto Hernández Pérez. Rev. Jun 2013

6-3


Las clases

no un objeto real. El código anterior no crea ningún objeto de la clase Caja. Para ello habrá que utilizar una sentencia como la siguiente:

Caja miCaja = new Caja(); // crea un objeto Caja llamado miCaja

Cada vez que creemos una instancia de una clase, estaremos creando un objeto que contiene su propia copia de cada variable de instancia definida por la clase. Por lo tanto, cada objeto Caja contendrá sus propias copias de las variables de instancia ancho, alto y largo. Para acceder a estas variables, utilizaremos el operador variable de instancia (.). Este operador liga el nombre del objeto con el nombre de una variable de instancia. La siguiente sentencia sirve para asignar a la variable ancho de miCaja el valor de 100.

miCaja.ancho = 100;

En general, el operador punto se usa para acceder tanto a las variables de instancia como a los métodos de un objeto.

El siguiente programa utiliza la clase Caja:

/* Un programa que utiliza la clase Caja. El nombre de este fichero es CajaDemo.java. */ class Caja { double ancho; double alto; double largo; } // Esta clase declara un objeto de la clase Caja. class CajaDemo { public static void main(String args[]) { Caja miCaja = new Caja(); double vol; // asignación de valores a las variables de instancia de miCaja miCaja.ancho = 10; miCaja.alto = 20; miCaja.largo = 15;

Instituto Tecnológico de Pachuca – Roberto Hernández Pérez. Rev. Jun 2013

6-4


Las clases

// calculo del volumen de miCaja vol = miCaja.ancho * miCaja.alto * miCaja.largo; }

System.out.println("El volumen es " + vol);

}

Este programa se debe llamar CajaDemo.java, ya que el método main() está dentro de la clase denominada CajaDemo. Cuando se compila este programa, se generan dos ficheros .class, uno para Caja y otro para CajaDemo. El compilador Java crea automáticamente para cada clase su propio fichero .class. No es necesario que las clases Caja y CajaDemo estén en el mismo fichero fuente.

Para ejecutar este programa, debemos ejecutar CajaDemo.class, y obtendremos la siguiente salida:

El volumen es 3000.0

Es importante tener en cuenta que los cambios en las variables de instancia de un objeto no afectan a las variables de otro. El siguiente programa declara dos objetos Caja.

// Este programa declara dos objetos Caja. class Caja { double ancho; double alto; double largo; } // Esta clase declara un objeto de la clase Caja. class CajaDemo2 { public static void main(String args[]) { Caja miCaja1 = new Caja(); Caja miCaja2 = new Caja(); double vol; // asignacion de valores a las variables de instancia de miCaja1 miCaja1.ancho = 10; miCaja1.alto = 20; miCaja1.largo = 15; /* asignación de valores diferentes a las variables de instancia de miCaja2 */

Instituto Tecnológico de Pachuca – Roberto Hernández Pérez. Rev. Jun 2013

6-5


Las clases

miCaja2.ancho = 3; miCaja2.alto = 6; miCaja2.largo = 9; // Calculo del volumen de la primera caja vol = miCaja1.ancho * miCaja1.alto * miCaja1.largo; System.out.println("El volumen es " + vol);

}

// Calculo del volumen de la segunda caja vol = miCaja2.ancho * miCaja2.alto * miCaja2.largo; System.out.println("El volumen es " + vol);

}

La salida que se obtiene es la siguiente: El volumen es 3000.0 El volumen es 162.0

Declaración de objetos Cuando se crea una clase, se está creando un nuevo tipo de datos que se utilizará para declarar objetos de ese tipo. Sin embargo, la obtención de objetos de una clase es un proceso que consta de dos etapas. En primer lugar, se debe declarar una variable del tipo de la clase. Esta variable no define un objeto, sino que simplemente es una referencia a un objeto. En segundo lugar se debe obtener una copia física del objeto y asignarla a esa variable. Para ello se utiliza el operador new.

Caja miCaja = new Caja();

Está sentencia combina las dos etapas descritas anteriormente.

El operador new

El operador new reserva memoria dinámicamente para un objeto. Su forma general es:

Instituto Tecnológico de Pachuca – Roberto Hernández Pérez. Rev. Jun 2013

6-6


Las clases

variable = new nombre_de_la_clase ();

Siendo variable una variable del mismo tipo de la clase creada, y el nombre_de_la_clase, el nombre de la clase que está siendo instanciada. El constructor de la clase viene especificado por el nombre de la clase seguido por paréntesis.

Es importante tener en cuenta que el operador new reserva memoria para un objeto durante el tiempo de ejecución. La ventaja de hacerlo así es que el programa crea los objetos que exactamente necesita durante su ejecución. Sin embargo, ya que la memoria disponible es finita, puede ocurrir que ese operador new no sea capaz de reservar memoria para un objeto porque no exista ya memoria disponible.

Asignación de variables de referencia a objetos

Las variables de referencia a objetos actúan de una forma diferente a la que cabría esperar cuando tiene lugar una asignación. Por ejemplo, el siguiente fragmento de código:

Caja b1 = new Caja();

Caja b2 = b1;

Cuando este fragmento de código se ejecute, b1 y b2 se referirán al mismo objeto. La asignación de b1 a b2 no reserva memoria ni copia parte alguna del objeto original. Simplemente hace que b2 se refiera al mismo objeto que b1. Por lo tanto, cualquier cambio que se haga en el objeto a través de b2 afectará al objeto al que se refiere b1, ya que, en definitiva, se trata del mismo objeto.

Aunque b1 y b2 se refieren al mismo objeto, no están relacionados de ninguna otra forma.

Instituto Tecnológico de Pachuca – Roberto Hernández Pérez. Rev. Jun 2013

6-7


Las clases

Métodos

El concepto de método es muy amplio. La forma general de un método es la siguiente:

Tipo nombre_de_método (lista de parámetros) { // cuerpo del método } donde tipo especifica el tipo de dato que devuelve el método, que puede ser cualquier tipo válido, incluyendo los tipos de clases creadas por el programador. Cuando el método no devuelve ningún valor, el tipo devuelto debe ser void. El nombre del método se especifica en nombre_de_método, que puede ser cualquier identificador válido que sea distinto de los que ya están siendo utilizados por otros elementos del programa. La lista de parámetros es una sucesión de pares de tipo e identificador separados por comas. Los parámetros son variables que reciben los valores de los argumentos que se pasa a los métodos cuando se les llama. Si el método no tiene parámetros, la lista de parámetros estará vacía.

Los métodos que devuelven un tipo diferente del tipo void devuelven el valor a la rutina llamante mediante la siguiente forma de la sentencia return:

return valor;

Adición de un método a la clase Caja

Los métodos definen la interfaz para la mayor parte de las clases. Esto permite que la clase oculte la estructura interna de los datos detrás de las abstracciones de un conjunto de métodos. Además de definir métodos que proporcionen el acceso a los datos, también se pueden definir métodos cuyo propósito el de ser utilizados internamente por la propia clase.

Instituto Tecnológico de Pachuca – Roberto Hernández Pérez. Rev. Jun 2013

6-8


Las clases

Comencemos por añadir un método a la clase Caja. En los programas anteriores se calculaba el volumen de una caja en la clase CajaDemo; sin embargo, el volumen de la caja depende del tamaño de la caja. Por este motivo tiene más sentido que sea la clase Caja la que se encargue del cálculo del volumen. Para ello se debe añadir un método a la clase Caja, tal y como se muestra a continuación:

// Este programa incluye un método en la clase Caja.

class Caja { double ancho; double alto; double largo;

}

// presenta el volumen de una caja void volumen() { System.out.print("El volumen es "); System.out.println(ancho * alto * largo); }

class CajaDemo3 { public static void main(String args[]) { Caja miCaja1 = new Caja(); Caja miCaja2 = new Caja(); // asignacion de valores a las variables de instancia de miCaja1 miCaja1.ancho = 10; miCaja1.alto = 20; miCaja1.largo = 15; // asignacion de valores diferentes a las variables de instancia de miCaja2 miCaja2.ancho = 3; miCaja2.alto = 6; miCaja2.largo = 9; // Presenta el volumen de la primera caja miCaja1.volumen();

}

// Presenta el volumen de la segunda caja miCaja2.volumen();

}

Instituto Tecnológico de Pachuca – Roberto Hernández Pérez. Rev. Jun 2013

6-9


Las clases

Este programa genera la siguiente salida, que es la misma que se obtuvo en la versión anterior.

El volumen es 3000.0 El volumen es 162.0

Analicemos las dos líneas del código siguientes:

miCaja1.volumen(); miCaja2.volumen();

La primera invoca al método volumen() en miCaja1, es decir, llama al método volumen(), relativo al objeto miCaja1, utilizando el nombre del objeto seguido por el operador punto. Por lo tanto, la llamada al método miCaja1.volumen() presenta el volumen de la caja definida por miCaja2. Cada vez que se llama a volumen() se presenta el volumen de la caja especificada.

Un método de Java es una forma de implementar subrutinas.

Devolución de un valor

Una forma mejor de implementar el método volumen( ) es realizar el cálculo del volumen y devolver el resultado a la parte del programa que llama al método. En el siguiente ejemplo, que es una versión mejorada del programa anterior, se hace así.

// Ahora volumen() devuelve el volumen de una caja. class Caja { double ancho; double alto; double largo; // Calculo y devolución del valor double volumen() {

Instituto Tecnológico de Pachuca – Roberto Hernández Pérez. Rev. Jun 2013

6-10


Las clases

}

return ancho * alto * largo;

} class CajaDemo4 { public static void main(String args[]) { Caja miCaja1 = new Caja(); Caja miCaja2 = new Caja(); double vol; // asignacion de valores a las variables de instancia de miCaja1 miCaja1.ancho = 10; miCaja1.alto = 20; miCaja1.largo = 15; // asignacion de valores diferentes a las variables de instancia de miCaja2 miCaja2.ancho = 3; miCaja2.alto = 6; miCaja2.largo = 9; // se obtiene el volumen de la primera caja vol = miCaja1.volumen(); System.out.println("El volumen es "+ vol); // se obtiene el volumen de la segunda caja vol = miCaja2.volumen(); System.out.println("El volumen es "+ vol); }

}

En este ejemplo, cuando se llama al método volumen( ), se coloca en la parte derecha de la sentencia de asignación. En la parte izquierda está la variable, en este caso vol, que recibirá el valor devuelto por volumen( ). Por lo tanto, después de que se ejecute la sentencia:

vol = miCaja1.volumen();

el valor de miCaja1.volumen( ) es 3.000 y este valor se almacene en vol.

Dos puntos importantes sobre la devolución de valores son:

 El tipo de datos devueltos por un método debe ser compatible con el tipo de return especificado por el método.

Instituto Tecnológico de Pachuca – Roberto Hernández Pérez. Rev. Jun 2013

6-11


Las clases

 La variable que recibe el valor devuelto por un método (vol, en este caso) debe ser también compatible con el tipo de return especificado por el método. Métodos con parámetros

Los parámetros permiten generalizar un método, es decir, un método con parámetros puede operar sobre gran variedad de datos y/o ser utilizado en un gran número de situaciones diferentes. Para entender mejor este punto veamos el siguiente ejemplo. El siguiente método devuelve el cuadrado del número 10:

int cuadrado()

{ }

return 10 * 10;

Este método devuelve el cuadrado de 10, pero es muy limitado. Si se modifica de forma que tome un parámetro, como se muestra a continuación, entonces se consigue que cuadrado( ) tenga una mayor utilidad.

int cuadrado(int i)

{ return i * i; }

En este caso, cuadrado( ) es ahora un método de propósito general que puede calcular el cuadrado de cualquier número entero.

Es importante tener una idea precisa de estos dos términos, parámetros y argumentos. Un parámetro es una variable, definida por un método, que recibe un valor cuando se llama al método. Un argumento es un valor que se pasa a un método cuando se le llama.

Se puede utilizar un método parametrizado para mejorar la clase Caja. En los ejemplos anteriores, las dimensiones de caja se establecen por separado mediante una sucesión de sentencias:

Instituto Tecnológico de Pachuca – Roberto Hernández Pérez. Rev. Jun 2013

6-12


Las clases

miCaja1.ancho = 10; miCaja1.alto = 20; miCaja1.largo = 15;

Este código funciona, pero presenta problemas por dos razones. En primer lugar, resulta torpe y propenso a errores. En segundo lugar, sólo se puede acceder a las variables de instancia por medio de métodos definidos por sus clases. Se puede alterar el comportamiento de un método, pero no el de una variable de instancia accesible desde el exterior de la clase.

Una solución mejor es crear un método que tome las dimensiones de la caja dentro de sus parámetros y establezca las variables de instancia apropiadamente. En el siguiente programa se implementa este concepto:

// Este programa usa un método parametrizado.

class Caja { double ancho; double alto; double largo; // Calculo y devolución del volumen double volumen() { return ancho * alto * largo; }

}

// Establece las dimensiones de la caja Caja void setDim(double w, double h, double d) { ancho = w; alto = h; largo = d; }

class CajaDemo5 { public static void main(String args[]) { Caja miCaja1 = new Caja(); Caja miCaja2 = new Caja(); double vol; // Inicializa cada caja miCaja1.setDim(10,20,15); miCaja2.setDim(3,6,9); // Se obtiene el volumen de la primera caja vol = miCaja1.volumen();

Instituto Tecnológico de Pachuca – Roberto Hernández Pérez. Rev. Jun 2013

6-13


Las clases

System.out.println("El volumen es "+ vol); // Se obtiene el volumen de la segunda caja vol = miCaja2.volumen(); System.out.println("El volumen es "+ vol); }

}

El método setDim( ) se utiliza para establecer las dimensiones de cada caja.

Constructores

El proceso de inicialización es tan común que Java permite que los objetos se inicialicen cuando son creados. Esta inicialización automática se lleva a cabo mediante un constructor.

Un constructor inicializa un objeto inmediatamente después de su creación. Tiene el mismo nombre que la clase en la que reside y, sintácticamente, es similar a un método. Una vez definido, se llama automáticamente al constructor después de crear el objeto y antes de que termine el operador new. Los constructores no devuelven ningún tipo, ni siquiera void. La tarea del constructor es inicializar el estado interno de un objeto de forma que el código que crea una instancia tenga una inicialización completa, que podrá ser utilizada por el objeto inmediatamente.

Se puede modificar el ejemplo anterior de forma que las dimensiones de la caja se inicialicen automáticamente cuando se construye el objeto. Para ello se sustituye el método setDim( ) por un constructor.

/* La clase Caja usa un constructor para inicializar las dimensiones de una caja. */ class Caja { double ancho; double alto; double largo; // Este es el constructor para caja Caja() {

Instituto Tecnológico de Pachuca – Roberto Hernández Pérez. Rev. Jun 2013

6-14


Las clases

}

}

System.out.printIn(“Constructor de caja”); ancho = 10; alto = 10; largo = 10;

// Calculo y devolución del valor double volumen() { return ancho * alto * largo; }

class CajaDemo6 { public static void main(String args[]) { Caja miCaja1 = new Caja(); Caja miCaja2 = new Caja(); double vol; // Se obtiene el volumen de la primera caja vol = miCaja1.volumen(); System.out.println("El volumen es "+ vol);

}

}

// Se obtiene el volumen de la segunda caja vol = miCaja2.volumen(); System.out.println("El volumen es "+ vol);

Cuando se ejecuta este programa, genera el siguiente resultado: Constructor de Caja Constructor de Caja El volumen es 1000.0 El volumen es 1000.0

Como puede observarse, miCaja1 y miCaja2 han sido inicializados por el constructor de Caja( ) en el momento de su creación. Como el constructor asigna el mismo valor, 10, a todas las dimensiones de la caja, miCaja1 y miCaja2 tienen el mismo volumen. La mayoría de los constructores no presentan ninguna salida, sino que simplemente inicializan un objeto.

Examinemos el operador new. Cuando se reserva espacio de memoria para un objeto, se hace de la siguiente forma:

Instituto Tecnológico de Pachuca – Roberto Hernández Pérez. Rev. Jun 2013

6-15


Las clases

variable = new nombre de clase( );

Ahora resulta evidente la necesidad de los paréntesis después del nombre de clase. Lo que ocurre realmente es que se está llamando al constructor de la clase. Por lo tanto, en la línea:

Caja miCaja1 = new Caja();

new Caja( ) es la llamada al constructor de Caja( ).

Constructores con parámetros

Necesitamos una forma de construir objetos Caja de diferentes dimensiones. La solución más sencilla es añadir parámetros al constructor, con lo que se consigue que este sea mucho más útil. La siguiente versión de Caja define un constructor con parámetros que asigna a las dimensiones de la caja los valores especificados por esos parámetros.

/* Aquí, Caja usa un constructor parametrizado inicializa las dimensiones de una caja. */ class Caja { double ancho; double alto; double largo; // Este es el constructor para caja Caja(double w, double h, double d) { ancho = w; alto = h; largo = d; } // calculo y devolucion del valor double volumen() { return ancho * alto * largo; } }

Instituto Tecnológico de Pachuca – Roberto Hernández Pérez. Rev. Jun 2013

6-16


Las clases

class CajaDemo7 { public static void main(String args[]) { Caja miCaja1 = new Caja(10, 20, 15); Caja miCaja2 = new Caja(3, 6, 9); double vol; // se obtiene el volumen de la primera caja vol = miCaja1.volumen(); System.out.println("El volumen es "+ vol);

}

}

// Se obtiene el volumen de la segunda caja vol = miCaja2.volumen(); System.out.println("El volumen es "+ vol);

La salida de este programa es la siguiente:

El volumen es 3000.0 El volumen es 162.0

La palabra clave: this

Un método necesita referirse al objeto que lo invocó. Para permitir esta situación, Java define la palabra clave this, que puede ser utilizada dentro de cualquier método para referirse al objeto actual. this es siempre una referencia al objeto sobre el que ha sido llamado el método. Se puede usar this siempre que esté permitida una referencia a un objeto del mismo tipo de la clase actual.

Consideremos la siguiente versión de Caja( ): para comprender mejor cómo funciona this.

// Un uso redundante de this. Caja (double w, double h, double d) { this.ancho = w; this.alto = h; this.largo = d; }

Instituto Tecnológico de Pachuca – Roberto Hernández Pérez. Rev. Jun 2013

6-17


Las clases

Está versión de Caja( ) opera exactamente igual que la versión anterior. El uso de this es redundante pero correcto. Dentro de Caja( ), this se refiere siempre al objeto llamante.

Recogida de basura

Ya que en Java se reserva espacio de memoria para los objetos dinámicamente mediante la utilización de operador new, surge la cuestión de cómo destruir los objetos y liberar el correspondiente espacio de memoria para su posterior utilización. Java gestiona automáticamente la liberación de la memoria. Esta técnica se denomina recogida de basura y consiste en lo siguiente: cuando no existen referencias a un objeto, se supone que no se va a necesitar ya, y la memoria ocupada por dicho objeto puede ser recuperada. Sólo se produce esporádicamente, si es necesario, durante la ejecución del programa.

El método finalize()

Java proporciona un mecanismo denominado finalización mediante el cual se pueden definir acciones específicas que producirán cuando el sistema de recogida de basura vaya a eliminar un objeto. Para añadir un finalizador a una clase basta con definir el método finalize() se especificaran aquellas acciones que se han de efectuar antes de destruir un objeto. Justo antes de eliminar un objeto, el intérprete de Java llama al método finalize() de ese objeto.

El método finalize() tiene la siguiente forma general: Protected void finalize() { // Código de finalización }

donde la palabra clave protected es un especificador que impide el acceso a finalize() por parte de un código definido fuera de su clase.

Instituto Tecnológico de Pachuca – Roberto Hernández Pérez. Rev. Jun 2013

6-18


Las clases

La clase Stack

Una pila (stack) almacena los datos de manera que se retiran en orden inverso al de entrada, es decir, un stack es como una pila de platos encima de una mesa el primer plato puesto encima de la mesa es el último en ser utilizado. Las piladas se controlan mediante dos operaciones tradicionales denominadas push y pop. Para colocar un dato en la parte superior de la pila se utiliza la operación de push, y para retirarlo, la de pop. Resulta sencillo encapsular el mecanismo completo de una pila.

// Esta clase define un pila de enteros que puede almacenar hasta 10 valores class Stack { int stck [] = new int [10]; int tos; //Inicializa la parte superior de la pila Stack() { tos = -1; } // Situa un dato en la pila void push (int ítem) { if (tos==9) System.out.printIn(“La pila está llena.”); else stck[++tos] = ítem; } //Retira un dato de la pila int pop() { if(tos < 0) { System.out.printIn(“La pila esta vacía.”); return 0; } else return stck[tos-]; } }

Instituto Tecnológico de Pachuca – Roberto Hernández Pérez. Rev. Jun 2013

6-19


Turn static files into dynamic content formats.

Create a flipbook
Issuu converts static files into: digital portfolios, online yearbooks, online catalogs, digital photo albums and more. Sign up and create your flipbook.