You are on page 1of 70

‡ Se explicará, en primer lugar, qué son las clases y los objetos, paso fundamental para poder programar en Java. Veremos, a continuación, que una clase puede contener atributos y métodos en su interior, por lo que también. Estudiaremos cómo se relacionan las clases mediante la herencia y, por último, explicaremos cómo se crean y utilizan los paquetes en Java

‡ Capacidad para encapsular y aislar la información del diseño y ejecución. ‡ Mecanismos en programación:  Procedimientos y funciones  Tipos de datos abstractos (TDA)  Objetos: son TDA a los que se añaden mecanismos como herencia, métodos, etc.

. veremos que el disco duro está compuesto por varios discos superpuestos. La mejor forma de entenderlo es mediante una analogía. etc. Si lo abrimos y lo observamos detenidamente. ¿qué es un objeto?. El lenguaje C no está orientado a objetos. C++ sí lo está. habrás oído hablar de lenguajes orientados y no orientados a objetos. te lo cuento yo). las cabezas lectoras.‡ Si sabes algo sobre programación (y si no. el procesador. y cada pieza está compuesta por partes más pequeñas. Java también. Consideremos un ordenador. examinamos por separado cada parte. un circuito controlador. ‡ Pero. la memoria. a su vez. Pensar en objetos supone tener que cambiar el chip para enfocar la resolución de problemas de una manera distinta a como se ha hecho tradicionalmente. y lo mismo ocurre con todas las demás partes del ordenador: el todo está formado por piezas. Podemos ver también que cada módulo de memoria está construido a partir de circuitos integrados de memoria más pequeños interconectados entre sí. por ejemplo. el disco duro. podemos comprobar que está formado por la placa base. Si. etc.

existen en la industria estándares gracias a los cuales cada empresa puede fabricar internamente los discos duros como mejor les parezca.). SCSI.‡ Supongamos que se nos estropea el disco duro y necesitamos comprar otro. . tenemos un objeto (el disco duro) que realiza una función determinada (almacenar información) sobre unos atributos (los datos). éstos serían incompatibles entre sí. Si cada fabricante de PCs diseñara discos duros para sus ordenadores basándose en especiĮcaciones propias. y que se comunica con el resto del sistema mediante una interfaz determinada y bien conocida. ‡ Por suerte. siempre y cuando la interfaz de conexión con el ordenador cumpla con un estándar determinado y aceptado por todos los fabricantes (IDE. etc. y nos veríamos obligados a buscar el modelo de disco adecuado para nuestro ordenador. De este modo.

Así que tenemos una serie de objetos (las piezas) con una interfaz común (las hendiduras) y que nos permiten realizar una construcción (el programa). . usaré un ejemplo más sencillo. permitiendo el acceso sólo a través de una interfaz bien conocida y deĮnida.  Proporcionan encapsulación: Es posible ocultar las partes internas de la implementación de un objeto. Bueno.‡ ¿Nunca has abierto un ordenador y no sabes lo que hay dentro?. Cualquier juego de construcción como los de Lego o Tente está formado por elementos básicos (las piezas). por sí sola. pero podemos juntarlas para construir lo que nos dé la gana. Si podemos construir cosas es porque cada pieza trae una serie de hendiduras que encajan en las de las demás. no tiene mucha utilidad. ‡ Mediante estos ejemplos ya podemos vislumbrar algunas de las características de los objetos:  Realizan una tarea por sí solos. Cada pieza.

. y los juntaremos para crear un programa. para crear objetos. Son reutilizables. Programaremos una serie de objetos independientes con una funcionalidad determinada. primero debemos hablar de las clases.  Proporcionan escalabilidad (el programa puede crecer) y modularidad (el programa se puede dividir en bloques que faciliten su comprensión). ‡ En Java ocurre lo mismo que en los ejemplos anteriores. Pero.

sin especiĮcar de qué tipo de coche se trata. se muestran un Seat Panda. A partir de esa clase Coche.. Todos ellos comparten una serie de características comunes por las que podemos identiĮcarlos como coches. Una clase es la unidad fundamental en programación. como se muestra en la Įgura 2. Atributos y Métodos  Cuando escribimos un programa en un lenguaje orientado a objetos. un Opel Corsa.  Supongamos que deĮnimos una clase Coche. podremos crear nuestros objetos (también llamados instancias). Es la plantilla que utilizaremos posteriormente para crear un conjunto de objetos con características similares. Es una abstracción. sino clases. .1. No tiene entidad física. Podemos asignarle un comportamiento y una serie de características. Hablamos de un coche en general. que serán las realizaciones ͟físicas͟ de la clase. la pieza de Lego. y un Renault Megane..‡ Clases en Java. El problema es. En el ejemplo. no estamos deĮniendo objetos. que no existe.

1): . Esos son los métodos de la clase.3. Atributos y Métodos  Vemos en la ¿gura que. color. podemos arrancar y detener nuestro coche. Para de¿nir nuestra clase en Java. tenemos las variables estadoMotor. y modelo. respecto al comportamiento. lo haremos de la siguiente manera (programa 2. En cuanto a las características (llamadas atributos).‡ Clases en Java.

out.3. else{ estadoMotor=true.println("El coche ya está arrancado"). class Coche { boolean estadoMotor = false. else{ estadoMotor=false.println("El coche ya está detenido").println("Coche detenido").out. String color. } } void detener(){ if(estadoMotor == false) System.out.1 La clase Coche. String modelo. } } } // fin de la clase Coche . System.Programa 2.println("Coche arrancado").out. void arrancar(){ if(estadoMotor == true) System. System.

 A continuación tenemos tres atributos. por norma. Es decir. de un color. Todo el código que pertenezca a esa clase se encierra entre dos llaves.  Los atributos nos deĮnen las características que tendrá cada objeto de esa clase.  Por último. cada coche será de un modelo determinado. deĮnidos por las variables estado Motor. arrancar() y detener().  En nuestro ejemplo. podremos arrancar o detener el motor de nuestros coches. y su motor estará encendido o apagado. tenemos dos métodos. y que podrán  ser distintas para cada uno de ellos. color y modelo. . comienzan con mayúscula. Los métodos nos deĮnen el comportamiento que tendrán los objetos de esa clase.Analicemos paso a paso cada parte de la clase:  Las clases se deĮnen con la palabra reservada class.  Los nombres de las clases.

sin considerar su estado. . por un número de modelo. Además. son todas las acciones (denominadas operaciones) que el objeto puede realizar por sí mismo. o modificar. ‡ Identidad: El objeto tiene una identidad.‡ Atributos: estos son los datos que caracterizan al objeto. etc. Estas operaciones hacen posible que el objeto responda a las solicitudes externas (o que actúe sobre otros objetos). que lo distingue de otros objetos. los valores de un atributo. Son variables que almacenan datos relacionados al estado de un objeto. esta identidad se crea mediante un identificador que deriva naturalmente de un problema (por ejemplo: un producto puede estar representado por un código. un automóvil. ‡ Métodos (usualmente llamados funciones de miembro): Los métodos de un objeto caracterizan su comportamiento. es decir. Por lo general. ya que sus acciones pueden depender de.). las operaciones están estrechamente ligadas a los atributos.

borrar. evitando el acceso a datos por cualquier otro medio distinto a los especificados.  El concepto de encapsulación:  La encapsulación es un mecanismo que consiste en organizar datos y métodos de una estructura. la encapsulación garantiza la integridad de los datos que contiene un objeto. . Por lo tanto. conciliando el modo en que el objeto se implementa.‡ El modelo objeto  Abstracción Las características esenciales del objeto Documento: insertar... . es decir.

se garantiza la integridad de los datos (por ejemplo. permitiéndonos el acceso a datos a través de un método de esa clase en particular. uno puede asegurarse de que el tipo de datos suministrados cumple con nuestras expectativas bien que los se encuentran dentro del periodo de tiempo esperado). un usuario no necesita conocer la implementación Al evitar que el usuario modifique los atributos directamente y forzándolo a utilizar funciones definidas para modificarlos (llamadas interfaces). Existen tres niveles de acceso: .‡ Ocultación de datos  El usuario de una clase en particular no necesita saber cómo están estructurados los datos dentro de ese objeto. desde una clase heredada o incluso desde cualquier otra clase. es decir.  La encapsulación define los niveles de acceso para elementos de esa clase. Estos niveles de acceso definen los derechos de acceso para los datos.

desde una clase heredada o incluso desde cualquier otra clase. permitiéndonos el acceso a datos a través de un método de esa clase en particular. Existen tres niveles de acceso: . Estos niveles de acceso definen los derechos de acceso para los datos. La encapsulación define los niveles de acceso para elementos de esa clase.

Este es el nivel de protección de datos más bajo protegido: el acceso a los datos está restringido a las funciones de clases heredadas. Este es nivel más alto de protección de datos .público: funciones de toda clase pueden acceder a los datos o métodos de una clase que se define con el nivel de acceso público. las funciones miembro de esa clase y todas las subclases privado: el acceso a los datos está restringido a los métodos de esa clase en particular. es decir.

En realidad. donde una clase nueva se crea a partir de una clase existente.  El concepto de herencia:  La herencia es específica de la programación orientada a objetos. . existe una relación más compleja entre clases.‡ Herencia  Por lo explicado hasta ahora. podría parecer que la programación orientada a objetos se basa simplemente en crear clases independientes que se relacionan entre sí. que luego se aplican a los atributos y métodos heredados. Es la herencia. La principal ventaja de la herencia es la capacidad para definir atributos y métodos nuevos para la subclase. La herencia (a la que habitualmente se denomina subclases) proviene del hecho de que la subclase (la nueva clase creada) contiene las atributos y métodos de la clase primaria.

 Todas las clases en Java existen dentro de una jerarquía. Cada clase tiene una (y sólo una) clase por encima de ella, denominada superclase, y cualquier número de clases (o ninguna) por debajo.  A estas ´ultimas se las denomina subclases.  Una clase heredaría los métodos y variables de su superclase. Del mismo modo, sus subclases heredarán los métodos y variables de esa clase.

 Observemos la figura 2.2. En ella se muestran 5 clases y su relación de herencia. Por encima de todas tenemos una superclase Animal, con un atributo peso y un método comer() (todos los animales tienen peso y comen). Debajo de ésta aparecen otras dos clases con tipos de animales: Ovíparos y Mamiferos1 . Los Ovíparos pueden ponerHuevos(). Los Mamíferos pueden parir() y amamantar() a sus crías, y pueden tener la sangreCaliente, o no (el tipo boolean especifica que ese atributo puede ser cierto o falso). Estas dos clases, aparte de tener su propio comportamiento y sus características, heredan también los métodos y atributos de su superclase. Por ello, tanto los Mamíferos como los Ovíparos pueden comer() y tienen un peso.  Asimismo, la clase Mamífero tiene dos subclases que heredan de ella. Son las subclases Perro y Delfín. El perro, por ejemplo, tendrá un color de pelo determinado, y podrá ladrar. Y además, debido a la herencia, tendrá un peso, podrá comer, tendrá la sangre caliente y amamantará a sus crías.

 ¿Queda claro?. Cada subclase extiende y concreta la funcionalidad y características de su superclase. Es decir, se ͟especializa͟ más.  Bien, supongamos que tenemos una clase escrita en Java. La manera de especificar que una clase es subclase de otra se hace utilizando la palabra reservada extends. En el siguiente ejemplo definiremos las clases Animal y Mamífero.  Programa 2.4.1 La clase Mamífero y su superclase Animal. class Animal{ float peso; void comer(){ } } class Mamifero extends Animal{ boolean sangreCaliente; void parir(){ } void amamantar(){ } }

cuando se programa. Aprovecho para comentar que. en vez de Mamífero. añadimos la coletilla extends Animal. El hecho de que una clase Java solo pueda heredar de su superclase se denomina herencia simple. claro. Por eso definimos la clase como Mamifero. como C++. al definir la clase Mamifero. Vemos que. y sólo una clase (excepto la claseObject. Pero no en Java. no se utilizan acentos. a estas alturas. están preguntando de quien hereda la clase Animal. .  Al principio de este apartado se explico que todas las clases existen dentro de una jerarquía y que siempre heredan de su superclase. Todas las clases heredan de una.  Esta clase es la superior en la jerarquía de clases de Java. heredaran de la clase Object. que no hereda de nadie). puesto que no hemos añadido ningún extends. En otros lenguajes. existe el concepto de herencia múltiple. y es la ´única que no hereda de nadie. Seguro que. lo cual simplifica enormemente la programación sin restarle potencia.  Un ultimo apunte.  La respuesta es que todas las clases en las que no se especifique nada. en el que una clase puede heredar de dos o más superclases. para especificar que heredamos de la clase Animal.

lo que significa que una clase puede heredar los atributos de otras dos superclases. Este método puede utilizarse para agrupar atributos y métodos desde varias clases dentro de una sola. Herencia múltiple  Algunos lenguajes orientados a objetos. como C++ permiten herencias múltiples. .

‡ Polimorfismo  El concepto de polimorfismo:  La palabra polimorfismo proviene del griego y significa que posee varias formas diferentes. Así como la herencia está relacionada con las clases y su jerarquía. hay tres tipos de polimorfismo: Polimorfismo de sobrecarga Polimorfismo paramétrico (también llamado polimorfismo de plantillas) Polimorfismo de inclusión (también llamado redefinición o subtipado) . Este es uno de los conceptos esenciales de una programación orientada a objetos. el polimorfismo se relaciona con los métodos.  En general.

 Por lo tanto. con funcionalidad similar. la clase complex. por ejemplo. Esto significa que no necesitamos preocuparnos sobre el tipo de objeto con el que estamos trabajando si todo lo que deseamos es verlo en la pantalla. agregar el operador + y hacer que se comporte de manera distinta cuando está haciendo referencia a una operación entre dos números enteros (suma) o bien cuando se encuentra entre dos cadenas de caracteres (concatenación).‡ Polimorfismo de sobrecarga  El polimorfismo de sobrecarga ocurre cuando las funciones del mismo nombre existen. Así es posible. . el polimorfismo de sobrecarga nos permite definir operadores cuyos comportamientos varían de acuerdo a los parámetros que se les aplican. en clases que son completamente independientes una de otra (éstas no tienen que ser clases secundarias de la clase objeto). la clase image y la clase link pueden todas tener la función "display". Por ejemplo.

. pero usando parámetros diferentes (nombre y/o tipo). El polimorfismo paramétrico selecciona automáticamente el método correcto a aplicar en función del tipo de datos pasados en el parámetro.‡ Polimorfismo de paramétrico  El polimorfismo paramétrico es la capacidad para definir varias funciones utilizando el mismo nombre.

 El método movimiento podría. se puede llamar un método de objeto sin tener que conocer su tipo intrínseco: esto es polimorfismo de subtipado.‡ Polimorfismo de subtipado  La habilidad para redefinir un método en clases que se hereda de una clase base se llama especialización. cada uno heredando el objeto pieza. torre y peón. caballo. Esto permite al programa realizar el movimiento.de_pieza sin tener que verse conectado con cada tipo de pieza en particular. . alfil. reina.  Imagine un juego de ajedrez con los objetosrey. hacer el movimiento correspondiente de acuerdo a la clase objeto que se llama. usando polimorfismo de subtipado. Por lo tanto. Permite no tomar en cuenta detalles de las clases especializadas de una familia de objetos. enmascarándolos con una interfaz común (siendo esta la clase básica).

‡ Modularidad  Subdivisión de una aplicación en otras más pequeñas (módulos). Fuente.  Un módulo es un conjunto de clases Editor. Documento. ͙ ‡ Otras propiedades  concurrencia (multitarea)  Persistencia (guardar)  uso de excepciones (errores) .

‡ Cronología resumida:  Fortran (1958)  LISP (1959)  BASIC (1964)  Pascal (1969)  Prolog (1971)  C++ (1986)  Object Pascal (1988)  CLOS (1989)  Java (1995) ‡ Beneficios:  Mejor mantenimiento  Estructuras más reales de la información  Escalabilidad  Adaptabilidad .

‡ Orígenes e historia del lenguaje Java  El lenguaje de programación Java fue desarrollado por Sun Microsystems en 1991. si se quería instalar en dispositivos tan heterogéneos y de distintos fabricantes. por entonces). como parte de un proyecto de investigación para desarrollar software que pudiera ejecutarse en todo tipo de dispositivos electrónicos domésticos. . eficiente y que generara un código muy pequeño. se buscaba que fuera un lenguaje rápido. Dado que estos aparatos no tenían mucha potencia ni memoria (al menos. el lenguaje debía ser independiente de la plataforma en la que se ejecutase. Además. como televisiones o frigoríficos.

 Distribuido: Java posee una extensa colección de herramientas que proporcionan la capacidad de trabajar en red de forma simple y robusta. Además. por ejemplo. Es prácticamente imposible. el aprendizaje de la sintaxis de Java es casi inmediato. . las estructuras.  Orientación a Objetos (OO): Cualquier lenguaje moderno est´a orientado a objetos. por lo que. como la aritmética de punteros. si se ha programado en C o en C++. etc.‡ Características de Java  Simplicidad: Java está basado en C++. escribir en una posición de memoria de otro programa. ya que su utilidad y ventajas con respecto a la programación tradicional orientada a procedimientos ha sido ampliamente demostrada en los últimos 30 años. Sin embargo. se modificaron o eliminaron ciertas características que en C++ son fuente de problemas. no debemos preocuparnos de la gestión de la memoria. Java se ocupa de descargar los objetos que no utilicemos.

que en otros lenguajes aparecerían en tiempo de ejecución. como la sobre escritura de posiciones de memoria. que se corrompa la memoria externa a un proceso. por lo que se ha cuidado mucho la seguridad. .  Seguro: Java esta pensado para ser utilizado en red. la eliminación del uso de punteros en elementos como cadenas de caracteres o arrays evita muchos problemas que son comunes (y difíciles de depurar) en C o C++. o que se pueda acceder a ficheros locales de un ordenador que esta ejecutando un applet en su navegador. Robusto: Como ya se comento antes. se supone que es capaz de evitar que se rebase la pila del sistema en tiempo de ejecución. El compilador detecta problemas. Java permite escribir programas fiables con mucho menor esfuerzo que en otros lenguajes. por ejemplo. Además. En principio.

es decir. Run Everywhere). puede ejecutarse en cualquier plataforma hardware con cualquier sistema operativo sin recompilar el código. que una vez escrito. . Un programa en Java sigue la filosofía WORE (Write Once. Independencia de la plataforma: He aquí una de las características más importantes y conocidas de Java.

Para utilizar una variable.  boolean motorEnMarcha. etc. un trozo de texto. .  char caracter. Estos valores pueden ser un numero. Cada variable tiene un tipo. Por ejemplo:  int numeroEntero. un carácter. un nombre y un valor.  String cadenaTexto. es preciso declararla primero.‡ Los comentarios en java pueden hacerse de dos formas: /* Esto es un comentario de varias líneas */ int variable. //Esto es un comentario al final de línea ‡ Las variables (a lo que se llama atributo) son zonas de memoria donde pueden almacenarse valores.

sólo es visible para las demás clases del package. }  Donde la palabra public es opcional: si no se pone... Las clases son como tipos de variables. esto es. ± Classname otroObjeto..‡ Concepto de Clase  Una clase es una agrupación de datos (variables o campos) y de funciones (métodos) que operan sobre esos datos. ± Classname unObjeto. mientras que los objetos son como variables concretas de un tipo determinado. la clase tiene la visibilidad por defecto. instance) es un ejemplar concreto de una clase. La definición de una clase se realiza en la siguiente forma: [public] class Classname { // definición de variables y métodos .  Un objeto (en inglés.} de la clase.. Todos los métodos y variables deben ser definidos dentro del bloque {. .

3. pero en un fichero no puede haber más que una clase public. Todas las variables y funciones de Java deben pertenecer a una clase. Si una clase deriva de otra (extends).‡ A continuación se enumeran algunas características importantes de las clases: 1. 4. lo habitual es escribir una sola clase por fichero. 5. La clase Object es la base de toda la jerarquía de clases de Java. por defecto la clase deriva de Object. Una clase sólo puede heredar de una única clase (en Java no hay herencia múltiple). Con algunas excepciones. Java tiene una jerarquía de clases estándar de la que pueden derivar las clases que crean los usuarios.java. En un fichero se pueden definir varias clases. 2. Este fichero se debe llamar como la clase public que contiene con extensión *. hereda todas sus variables y métodos. Si al definir una clase no se especifica de qué clase deriva. . No hay variables y funciones globales.

6.). Si una clase contenida en un fichero no es public. . Los métodos de una clase pueden referirse de modo global al objeto de esa clase al que se aplican por medio de la referencia this. 8. 9. introduciendo una línea al comienzo del fichero (package packageName. 7. no es necesario que el fichero se llame como la clase. Las clases se pueden agrupar en packages. Esta agrupación en packages está relacionada con la jerarquía de directorios y ficheros en la que se guardan las clases.

En algunos aspectos los nombres de las interfaces pueden utilizarse en lugar de las clases. Éste es un aspecto importante del polimorfismo. Una clase puede implementar más de una interface. Una interface.‡ Concepto de Interface  Una interface es un conjunto de declaraciones de funciones. las interfaces sirven para definir referencias a cualquier objeto de cualquiera de las clases que implementan esa interface.    . representando una alternativa a la herencia múltiple. Si una clase  implementa (implements). Una interface puede derivar de otra o incluso de varias interfaces. en cuyo caso incorpora las declaraciones de todos los métodos de las interfaces de las que deriva (a diferencia de las clases. Por ejemplo. debe definir todas las funciones especificadas por la interface. las interfaces de Java sí tienen herencia múltiple). sin embargo. sólo se pueden utilizar los métodos de la interface. Las interfaces pueden definir también variables finales (constantes). Con ese nombre o referencia.

0. public Circulo(double x.3. r. this. r).0. 1.0). this.0. double r) { this.0.4. double y.y. } public Circulo() { this(0. explicada en el Apartado 1. numCirculos++.r). public double x.x. public static final double PI=3. c.java public class Circulo extends Geometria { static int numCirculos = 0. } . } public double perimetro() { return 2.x=x. } public Circulo(double r) { this(0.0. } public Circulo(Circulo c) { this(c.14159265358979323846.‡ EJEMPLO DE DEFINICIÓN DE UNA CLASE  A continuación se reproduce como ejemplo la clase Circulo. y.0 * PI * r. c. 0.y=y. // fichero Circulo.r=r.

else return c. } } // fin de la clase Circulo En este ejemplo se ve cómo se definen las variables miembro y los métodos (cuyos nombres se han resaltado en negrita) dentro de la clase. . Dichas variables y métodos pueden ser de objeto o de clase (static).public double area() { return PI * r * r.r) return c. } // método de objeto para comparar círculos public Circulo elMayor(Circulo c) { if (this. Se puede ver también cómo el nombre del fichero coincide con el de la clase public con la extensión *.r>=c.java.r>=d. } // método de clase para comparar círculos public static Circulo elMayor(Circulo c.r) return this. else return d. Circulo d) { if (c.

int. el carácter nulo para char y cero para los tipos numéricos). Por eso las variables miembro de tipos primitivos se inicializan siempre de modo automático. ‡ Variables miembro de objeto  Cada objeto. lo más adecuado es inicializarlas también en el constructor. . Las variables miembro de una clase (también llamadas campos) pueden ser de tipos primitivos (boolean. ͙) o referencias a objetos de otra clase (composición). que estaba centrada en las funciones.‡ Variables Miembro  A diferencia de la programación algorítmica clásica. es decir cada ejemplar concreto de la clase.  Un aspecto muy importante del correcto funcionamiento de los programas es que no haya datos sin inicializar. la programación orientada a objetos está centrada en los datos. long. tiene su propia copia de las variables miembro. double. Una clase está constituida por unos datos y unos métodos que operan sobre esos datos. De todas formas. incluso antes de llamar al constructor (false para boolean.

en la página 131) y que el compilador no debe realizar optimizaciones con esta variable. transient: indica que esta variable miembro no forma parte de la persistencia (capacidad de los objetos de mantener su valor cuando termina la ejecución de un programa) de un objeto y por tanto no debe ser serializada (convertida en flujo de caracteres para poder ser almacenada en disco o en una base de datos) con el resto del objeto. private.  Existen otros dos modificadores (no de acceso) para las variables miembro: 1.3. volatile: indica que esta variable puede ser utilizada por distintas threads sincronizadas (ver Apartado 6. determinan qué clases y métodos van a tener permiso para utilizar la clase y sus métodos y variables miembro.  Junto con los modificadores de acceso de la clase (public y package). . Las variables miembro pueden ir precedidas en su declaración por uno de los modificadores de acceso: public. protected y package (que es el valor por defecto y puede omitirse). 2.

 Las variables de clase son lo más parecido que Java tiene a las variables globales de C/C++. porque de esta forma su sentido queda más claro. A estas variables se les llama variables de clase o variables static. Circulo. Por ejemplo. Las variables de clase se crean anteponiendo la palabra static a su declaración.numCirculos es una variable de clase que cuenta el número de círculos creados. un contador de objetos creados como numCirculos en la clase Circulo). Para llamarlas se suele utilizar el nombre de la clase (no es imprescindible. . pues se puede utilizar también el nombre de cualquier objeto). Las variables static se suelen utilizar para definir constantes comunes para todos los objetos de la clase (por ejemplo PI en la clase Circulo) o variables que sólo tienen sentido para toda la clase (por ejemplo.‡ Variables miembro de clase (static)  Una clase puede tener variables propias de la clase y no de cada objeto.

las variables miembro static se inicializan con los valores por defecto para los tipos primitivos (false para boolean. Lo importante es que las variables miembro static se inicializan siempre antes que cualquier objeto de la clase.  Las variables miembro static se crean en el momento en que pueden ser necesarias: cuando se va a crear el primer objeto de la clase. Si no se les da valor en la declaración. . en cuanto se llama a un método static o en cuanto se utiliza una variable static de dicha clase. el carácter nulo para char y cero para los tipos numéricos). y con null si es una referencia.

y equivale a la palabra const deC/C++. . también las variables locales y los propios argumentos de un método pueden ser declarados final. que puede ser modificado a través de otra referencia. En Java no es posible hacer que un objeto sea constante. Puede ser considerada como una constante.  Además de las variables miembro.  Java permite separar la definición de la inicialización de una variable final.  La variable final así definida es constante (no puede cambiar). pero no tiene por qué tener el mismo valor en todas las ejecuciones del programa.  Declarar como final un objeto miembro de una clase hace constante la referencia. llamando a métodos o en función de otros datos. La inicialización puede hacerse más tarde. pues depende de cómo haya sido inicializada. pero no el propio objeto. en tiempo de ejecución.‡ Variables Finales  Una variable de un tipo primitivo declarada como final no puede cambiar su valor a lo largo de la ejecución del programa.

Considérese el siguiente método omado de la clase Circulo: public Circulo elMayor(Circulo c) { // header y comienzo del método if (this.r>=c. el código comprendido entre las llaves {͙} es el cuerpo o body del método.‡ MÉTODOS (FUNCIONES MIEMBRO) ‡ Métodos de objeto  Los métodos son funciones definidas dentro de una clase.).  La primera línea de la definición de un método se llama declaración o header.r) // body return this. Los métodos pueden además tener otros argumentos explícitos que van entre paréntesis. Dicho objeto es su argumento implícito. se aplican siempre a un objeto de la clase por medio del operador punto (. a continuación del nombre del método. // body } // final del método . // body else // body return c. Salvo los métodos static o de clase.

r) o si alguna variable local o argumento las oculta. En cualquier caso no puede haber más que un único valor de retorno (que puede ser un objeto o un array). de modo discrecional (como en el ejemplo anterior con this. void si no tiene).  El valor de retorno puede ser un valor de un tipo primitivo o una referencia. El objeto devuelto debe pertenecer a una clase que implemente esa interface. El header consta del cualificador de acceso (public. del nombre de la función y de una lista de argumentos explícitos entre paréntesis.). De todas formas. pero nunca de una superclase .  Los métodos tienen visibilidad directa de las variables miembro del objeto que es su argumento implícito. del tipo del valor de retorno (Circulo en este ejemplo. en este caso). Si no hay argumentos explícitos se dejan los paréntesis vacíos. pueden acceder a ellas sin cualificarlas con un nombre de objeto y el operador punto (. es decir. también se puede acceder a ellas mediante la referencia this. Se puede devolver también una referencia a un objeto por medio de un nombre de interface. separados por comas. Se puede devolver como valor de retorno un objeto de la misma clase que el método o de una sub-clase.

 Un método también puede declararse como synchronized (Ej: public synchronized double miMetodoSynch(){. Su visibilidad llega desde la definición al finaldel bloque en el que han sido definidas. No hace falta inicializar las variables locales en el punto en que se definen. C++. pero el compilador no permite utilizarlas sin haberles dado un valor.}).. Estas librerías son ficheros de funciones compiladas normalmente en lenguajes distintos de Java (C. Estos métodos tienen la particularidad de que sobre un objeto no pueden ejecutarse simultáneamente dos métodos que estén sincronizados . Fortran.). Los métodos pueden definir variables locales.  Si en el header del método se incluye la palabra native (Ej: public native void miMetodo(). Es la forma de poder utilizar conjuntamente funciones realizadas en otros lenguajes desde código escrito en Java. las variables locales no se inicializan por defecto.) no hay que incluir el código o implementación del método. etc. Este código deberá estar en una librería dinámica (Dynamic Link Library o DLL). A diferencia de las variables miembro..

2. se llama ese método. métodos distintos que tienen el mismo nombre. Java método concreto que debe llamar: sigue unas reglas para determinar el método concreto que debe llamar: 1. Java permite métodos parame trisados es decir. Si existe el método cuyos argumentos se ajustan exactamente al tipo de los argumentos de la llamada (argumentos actuales). int a long.  A la hora de llamar a un método sobrecargado. .) y se llama el método correspondiente. etc. se intenta promover los argumentos actuales al tipo inmediatamente superior (por ejemplo char a int. Si no existe un método que se ajuste exactamente. float a double. pero que se diferencian por el número y/o tipo de los argumentos.‡ Métodos parame trisados  Al igual que C++.

El valor de retorno no influye en la elección del método sobrecargado. No es posible crear dos métodos sobrecargados. Redefinir un método es dar una nueva definición. Una clase puede redefinir (override) un método heredado de una superclase.  Diferente de la sobrecarga de métodos es la redefinición. que sólo difieran en el valor de retorno. . 4. En realidad es imposible saber desde el propio método lo que se va a hacer con él.Si sólo existen métodos con argumentos de un tipo más restringido (por ejemplo. es decir con el mismo nombre. el programador debe hacer un cast responsabilizándose de esta manera de lo que pueda ocurrir explícito en la llamada. int en vez de long).  En este caso el método debe tener exactamente los mismos argumentos en tipo y número que el método redefinido 3.

Dentro de un método se pueden crear variables locales de los tipos primitivos o referencias.  En Java no se pueden pasar métodos como argumentos a otros métodos (en C/C++ se pueden pasar punteros a función como argumentos). El método recibe una copia del argumento actual. si se modifica esta copia. . el argumento original que se incluyó en la llamada no queda modificado. La forma de modificar dentro de un método una variable de un tipo primitivo es incluirla como variable miembro en una clase y pasar como argumento una referencia a un objeto de dicha clase. Las referencias se pasan también por valor. Lo que se puede hacer en Java es pasar una referencia a un objeto y dentro de la función utilizar los métodos de ese objeto. pero a través de ellas se pueden modificar los objetos referenciados.‡ Paso de argumentos a métodos  En Java los argumentos de los tipos primitivos se pasan siempre por valor.

Los argumentos formales de un método (las variables que aparecen en el header del método para recibir el valor delos argumentos actuales) tienen categoría de variables locales del método. Estas variables locales dejan de existir al terminar la ejecución del método1.floatValue().valueOf(numeroComoString).lang.). un objeto de la clase) o una referencia a otro objeto.  Donde el método valueOf(String) de la clase java. ese objeto puede encadenarse con otra llamada a otro método de la misma o de diferente clase y así sucesivamente. En este caso aparecerán varios métodos en la misma sentencia unidos por el operador punto (. ± float p = Float.Float devuelve un objeto de la clase Float sobre el que se aplica el método floatValue().978͟. por ejemplo: ± String numeroComoString = ͟8. . que finalmente devuelve una variable primitiva de tipo float.  Si un método devuelve this (es decir.

 Obsérvese que se pueden encadenar varias llamadas a métodos por medio del operador punto (.) que. Float f = Float. float p = f.floatValue(). como todos los operadores de Java excepto los de asignación. se ejecuta de izquierda a derecha .valueOf(numeroComoString).978͟. El ejemplo anterior se podía desdoblar en las siguientes sentencias: String numeroComoString = ͟8.

Math (sin().Math. en vez del nombre de un objeto de la clase (por ejemplo. para calcular el seno de un ángulo).lang. Los métodos de clase pueden recibir objetos de su clase como argumentos explícitos.sin(ang).  Los métodos y variables de clase se crean anteponiendo la palabra static. A estos métodos se les llama métodos de clase o static. Un ejemplo típico de métodos static son los métodos matemáticos de la clase java. cos(). pero no tienen argumento implícito ni pueden utilizar la referencia this. De ordinario el argumento de estos métodos será de un tipo primitivo y se le pasará como argumento explícito. pow(). puede también haber métodos que no actúen sobre objetos concretos a través del operador punto. Estos métodos no tienen sentido como métodos de objeto. exp().).‡ Métodos de clase (static)  Análogamente. etc. . Para llamarlos se suele utilizar el nombre de la clase.

es reservar memoria e inicializar las variables. Su argumento implícito es el objeto que se está creando.‡ Constructores  Un punto clave de la Programación Orientada Objetos es el evitar información incorrecta por no haber sido correctamente inicializadas las variables.  Los constructores no tienen valor de retorno (ni siquiera void) y su nombre es el mismo que el de la clase.  Un constructor es un método que se llama automáticamente cada vez que se crea un objeto de una clase. El segundo paso en la inicialización correcta de objetos es el uso de constructores. . La principal misión del constructor miembro de la clase. Java no permite que haya variables miembro que no estén inicializadas (Sí puede haber variables locales de métodos sin inicializar. Ya se ha dicho que Java inicializa siempre con valores por defecto las variables miembro de clases y objetos. pero el compilador da un error si se intentan utilizar sin asignarles previamente un valor).

 Un constructor de una clase puede llamar a otro constructor previamente definido en la misma clase por medio de la palabra this. De esta forma. El programador debe proporcionar en el código valores iniciales adecuados para todas las variables miembro. seguida de los argumentos apropiados entre paréntesis. Se llama constructor por defecto al constructor que no tiene argumentos. De ordinario una clase tiene varios constructores.  El constructor de una sub-clase puede llamar al constructor de su super-clase por medio de la palabra super. . que se diferencian por el tipo y número de sus argumentos (son un ejemplo típico de métodos sobrecargados). la palabra this sólo puede aparecer en laprimera sentencia de un constructor. En este contexto. un constructor sólo tiene que inicializar por sí mismo las variables no heredadas.

private. . inicializando las variables de los tipos primitivos a su valor por defecto. el compilador crea un constructor por defecto. Si hace falta. protected y package.  Dentro de una clase. y los Stringsy las demás referencias a objetos a null. los constructores pueden tener también los modificadores de acceso public. Si un constructor es private. En este caso. ninguna otra clase puede crear un objeto de esa clase. puede haber métodos public y static (factory methods) que llamen al constructor y devuelvan un objeto de esa clase. El constructor es tan importante que. si el programador no prepara ningún constructor para una clase. No pueden ser llamados por los métodos de objeto de la clase. se llama al constructor de la superclase para que inicialice las variables heredadas  Al igual que los demás métodos de una clase. los constructores sólo pueden ser llamados por otros constructores o por métodos static.

sino una sola vez para toda la clase. que pueden ser static (para la clase) o de objeto. Los tipos primitivos pueden inicializarse directamente con asignaciones en la clase o en el constructor. en general. pero para inicializar objetos o elementos más complicados es bueno utilizar un inicializador (un bloque de código {͙}).‡ Inicializadores  Java todavía dispone de una tercera línea de actuación para evitar que haya variables sin inicializar correctamente. sin nombre y sin argumentos. situaciones anómalas que puede exigir ciertas actuaciones del propio programa o del usuario) con try͙catch. También se diferencia del constructor en que no es llamado para cada objeto. precedido por la palabra static) que se llama automáticamente al crear la clase (al utilizarla por primera vez). . Son los inicializadores. ya que permite gestionar excepciones(Las excepciones son situaciones de error o.  Inicializadores static Un inicializador static es un algo parecido a un método (un bloque {͙} de código.

loadLibrary("MyNativeLibrary"). } .loadLibrary(). esto es. Por ejemplo: o static{ System. En una clase pueden definirse varios inicializadores static.. Los inicializadores static se crean dentro de la clase. con tan sólo la palabra static y el código entre llaves {. como métodos sin nombre. a métodos escritos por ejemplo en C/C++ (llamando a los métodos System. Además se suelen utilizar para llamar a métodos nativos.  Los inicializadores static se pueden utilizar para dar valor a las variables static.. sin argumentos y sin valor de retorno. que se llamarán en el orden en que han sido definidos.load() o System.}. que leen las librerías nativas).

que no llevan la palabra static. que por no tener nombre no pueden tener constructor. . Se utilizan para las clases anónimas. En este caso. los inicializadores de objeto se llaman cada vez que se crea un objeto de la clase anónima. Inicializadores de objeto A partir de Java 1.1 existen también inicializadores de objeto.

Al crear el primer objeto de la clase o al utilizar el primer método o variable static se localiza la clase y se carga en memoria. Se ejecutan los inicializadores static (sólo una vez). 2) Se da valor por defecto a las variables miembro de los tipos primitivos .‡ Resumen del proceso de creación de un objeto  El proceso de creación de objetos de una clase es el siguiente: 1. Cada vez que se quiere crear un nuevo objeto: 1) Se comienza reservando la memoria necesaria. 2. 3. 3) Se ejecutan los inicializadores de objeto se ejecutan los constructores .

El sistema se ocupa automáticamente de liberar la memoria de los objetos que ya han perdido la referencia.‡ Destrucción de objetos (liberación de memoria)  En Java no hay destructores como en C++. . Java lleva internamente un contador de cuántas referencias hay sobre cada objeto. Como ya se ha dicho. porque a la referencia se le ha asignado el valor null o porque a la referencia se le ha asignado la dirección de otro objeto. haciendo por ejemplo:  ObjetoRef = null. esto es.  La esta característica de Java se le llama garbage collection (recogida de basura). por ejemplo por haber llegado al final del bloque en el que habían sido definidos. una forma de hacer que un objeto quede sin referencia es cambiar ésta a null.  En Java es normal que varias variables de tipo referencia apunten al mismo objeto. objetos que ya no tienen ningún nombre que permita acceder a ellos. El objeto podrá ser borrado cuando el número de referencias sea cero.

gc(). aunque esto es considerado por el sistema sólo como una ͞sugerencia͟ a la JVM.  Se puede llamar explícitamente al garbage collector con el método System. . En Java no se sabe exactamente cuándo se va a activar el garbage collector.

cerrar conexiones de red. etc. liberar memoria reservada por funciones nativas. sin valor de retorno (void).).  Un finalizador es un método de objeto (no static). utilizando la función malloc()). Se utilizan para ciertas operaciones de terminación distintas de liberar memoria (por ejemplo: cerrar ficheros. Si por ejemplo se ha reservado memoria con funciones nativas en C (por ejemplo. esta memoria hay que liberarla explícitamente utilizando el método finalize().  Un finalizador es un método que se llama automáticamente cuando se va a destruir un objeto (antes de que la memoria sea liberada de modo automático por el sistema).  Hay que tener en cuenta que el garbage collector sólo libera la memoria reservada con new. sin argumentos y que siempre se llama finalize(). .‡ Finalizadores  Los finalizadores son métodos que vienen a completar la labor del garbage collector.

 Los finalizadores se llaman de modo automático siempre que hayan sido definidos por el programador de la clase.  Tampoco se puede saber el momento preciso en que los finalizadores van a ser llamados.  El método System.1 hay que llamar primero a gc() y luego a runFinalization() . Para realizar su tarea correctamente. un finalizador debería terminar siempre llamando al finalizador de su super-clase. Para que este método se ejecute.runFinalization() ͞sugiere͟ a la JVM que ejecute los finalizadores de los objetos pendientes (que han perdido la referencia). en Java 1. En muchas ocasiones será conveniente que el programador realice esas operaciones de finalización de modo explícito mediante otros métodos que él mismo llame.

awt. en Java 1.2 hay 59 packages. Para que una clase pase a formar parte de un package llamado pkgName. como por ejemplo java.1 había 22 packages. que empiezan por mayúscula.  Además. hay que introducir en ella la sentencia:  package pkgName. para distinguirlos de las clases. En la API de Java 1. el usuario puede crear sus propios packages. lo que da una idea del ͞crecimiento͟ experimentado por el lenguaje. El nombre de un package puede constar de varios nombres unidos por puntos (los propios packages de Java siguen esta norma.‡ Qué es un package  Un package es una agrupación de clases.event). .  Que debe ser la primera sentencia del fichero sin contar comentarios y líneas en blanco.  Los nombres de los packages se suelen escribir con minúsculas.

ceit. Es recomendable que los nombres de las clases de Java sean únicos en Internet.ceit.class donde CLASSPATH es una variable de entorno del PC que establece la posición absoluta de los directorios en los que hay clases de Java (clases del sistema o de usuario). es. la clase.QuickSort. Por ejemplo.infor2.class debería estar en el directorio.ordenar  Las clases de un package se almacenan en un directorio con el mismo nombre largo (path) que el package.ordenar.  Los nombres compuestos de los packages están relacionados con la jerarquía de directorios en que se guardan las clases. .infor2. Es el nombre del package lo que permite obtener esta característica.jgjalon.jgjalon. CLASSPATH\es\ceit\jgjalon\infor2\ordenar\QuickSort. Todas las clases que forman parte de un package deben estar en el mismo directorio.  Una forma de conseguirlo es incluir el nombre del dominio (quitando quizás el país). como por ejemplo en el package siguiente:  es.

2. Para evitar conflictos de nombres (se recuerda que el dominio de nombres de Java es la Internet). Para ayudar en el control de la accesibilidad de clases y miembros. Para agrupar clases relacionadas. En este caso la posición del directorio es en los discos locales del ordenador. . 3. En caso de conflicto de nombres entre clases importadas.  Los packages se utilizan con las finalidades siguientes: 1. el compilador obliga a cualificar en el código los nombres de dichas clases con el nombre del package.

al mismo tiempo que se evitan los conflictos entre nombres.  Al importar un package no se importan los sub-packages.awt no se importa java. al importar java.  Si a pesar de todo hay conflicto entre nombres de clases. pues en realidad son packages distintos.‡ Cómo funcionan los packages  Con la sentencia import packname.  El importar un package no hace que se carguen todas las clases del package: sólo se cargarán las clases public que se vayan a utilizar. Java da un error y obliga a utilizar los nombres de las clases cualificados con el nombre del package. Por ejemplo.awt. . se puede evitar tener que utilizar nombres muy largos.event.  Éstos deben ser importados explícitamente.

ordenar.infor2.  Existen dos formas de utilizar import: para una clase y para todo un package:  import es.  Que deberían estar en el directorio:  classpath\es\ceit\jgjalon\infor2\ordenar .infor2.jgjalon. Se importan por defecto el package java.ceit.ceit.class.ordenar.  import es.jgjalon.lang y el package actual o por defecto (las clases del directorio actual).*.QuickSort.

una clase puede ser referida con su nombre completo (el nombre del package más el de la clase. Es posible guardar en jerarquías de directorios diferentes los ficheros *. variables y métodos.  Esto se puede hacer siempre de modo opcional.  La sentencia import permite abreviar los nombres de las clases. separados por un punto). pero es incómodo y hace más difícil el reutilizar el código y portarlo a otras máquinas. . evitando el tener que escribir continuamente el nombre del package importado. con objeto por ejemplo de no mostrar la situación del código fuente. Los packages hacen referencia a los ficheros compilados *.java.  En un programa de Java.  También se pueden referir con el nombre completo las variables y los métodos de las clases.class y *.class.