Está en la página 1de 34

Declaraciones y control de acceso

1. Objetivo de Certificacin 1.3 - Identificadores



Desarrollar cdigo que declare, inicialice y use tipos primitivos, enumerados y objetos como estticos,
instancias y variables locales. Adems, usar identificadores legales para el nombre de las variables.

Un identificador no es ms que el nombre que reciben las clases, los mtodos y las variables. Los
identificadores legales deben estar formados solo por caracteres UNICODE, nmeros, '$' y '_'. Utilice las
siguientes reglas para asignar los identificadores:
Deben empezar con letra (mayscula o minscula), '$' o '_'. ! No pueden empezar por un nmero!
Despus del primer carcter, los identificadores pueden contener cualquier letra, nmero, '$' o '_'.
No hay lmite en el nmero de caracteres que un identificador puede tener.
No pueden contener signos de puntuacin.
No podemos usar "palabras claves" como identificador.
Los identificadores en Java son "case sensitive" (distingue entre mayscula y minscula).

Ejemplos de identificadores legales:
int _a;
int $c;
int ______2_w;
int _$;
int this_is_a_very_detailed_name_for_an_identifier;

Ejemplos de identificadores ilegales:
int :b;
int -d;
int e#;
int .f;
int 7g;

Tabla con las palabras clave de Java que no podemos utilizar como identificador.




1.1. Convenciones del cdigo Java
Clases e interfaces: Las clases deben ser sustantivos. Su primer carcter debe ser mayscula el resto
puede ser maysculas y minusculas. Por ejemplo: MiClase
Las interfaces suelen ser adjetivos. Por ejemplo: Serializable, Runnable, ...
Mtodos: Los nombres de mtodos normalmente son verbos. Se escribe el primer carcter en minscula
y el resto minsculas y maysculas intercaladas. Por ejemplo: getNombre(), calcular().
Variables: Para las variables es igual que para los mtodos. Se recomiendan nombres cortos e
identificativos.
*Constantes: Son variables "static" y "final". Se deben escribir todo en maysculas con el carcter '_' para
separar las palabras.


2. Objetivo de Certificacin 1.4 - JavaBeans

Desarrollar cdigo que declare mtodos estticos y no estticos y usar nombres para los mtodos que se
ajusten al estndar de nombres de JavaBeans. Desarrollar cdigo que declare y use una lista de argumentos
variable.

2.1. Estndares JavaBeans

La especificacin de JavaBeans intenta ayudar a los desarrolladores Java a crear componentes Java que pueden
ser usados por otros desarrolladores de Java con una herramienta IDE como NetBeans o Eclipse. La
especificacin de JavaBeans garantiza que los IDE puedan reconocer y utilizar los componentes construidos por
diferentes desarrolladores.
La API de JavaBeans es grande, para el examen solo habr que estudiar algunos elementos bsicos.

En primer lugar, JavaBeans son clases Java que tiene propiedades. Para nuestro propsito, pensar que las
propiedades son instancias de variable private. As la nica manera de acceder a dichas propiedades desde fuera
de la clase es a travs de mtodos de la clase. Los mtodos que cambian el valor de las propiedades son mtodos
setter y los mtodos para recuperar el valor de las propiedades son getters.
Las normas de la nomenclatura de JavaBean que debemos saber para el examen son:
Si la propiedad no es un booleano, el prefijo del mtodo getter debe ser get. Por ejemplo, para la
propiedad size seria getSize().
Si la propiedad es un booleano, el prefijo del mtodo getteres get o is. Por ejemplo: getSttoped() o
isSttoped() ambos son validos.
El prefijo del mtodo setter debe ser set. Por ejemplo: setSize() es vlido para la propiedad size.
Para completar el nombre de un mtodo getter o setter, cambiamos el primer carcter de la propiedad a
mayscula y le ponemos el prefijo get, set o is respectivamente.
Los mtodos setter no devuelven nada (void) y tienen un argumento que representa el tipo de la
propiedad. Deben ser declarados public
Los mtodos getter no reciben argumentos y devuelven un tipo de la propiedad. Deben ser declarados
public

En segundo lugar, la especificacin JavaBeans soporta eventos, que permiten a componentes notificar a otros
que algo ha sucedido, son muy utilizados en aplicaciones GUI (por ejemplo click del ratn). Los objetos que
reciben la informacin de un evento ocurrido se llaman listeners (oyentes). Para el examen, es necesario que
sepamos que los mtodos que se utilizan para aadir o eliminar oyentes de un evento deben tambin seguir la
norma de denominacin de JavaBean, que pasamos a describir ahora:
Los nombres de los mtodos Listener, usados para "registrar" a un oyente en un evento, deben usar el
prefijo add seguido del tipo del oyente. Por ejemplo: addActionListener() es un nombre valido.
Los nombres de los mtodos Listener, usados para "eliminar" a un oyente en un evento, deben usar el
prefijo remove seguido del tipo del oyente. Por ejemplo: addActionListener() es un nombre valido.
El tipo del oyente que ser aadido o eliminado debe ser pasado como argumento al mtodo.

Ejemplos de mtodos JavaBeans vlidos:
public void setMyValue(int v)
public int getMyValue()
public boolean isMyStatus()
public void addMyListener(MyListener m)
public void removeMyListener(MyListener m)

Ejemplos de mtodos JavaBeans invlidos:
void setCustomerName(String s) // must be public
public void modifyMyValue(int v) // can't use 'modify'
public void addXListener(MyListener m) // listener type mismatch

3. Objetivo de Certificacin 1.1 - Declarar clases

Desarrollar cdigo que declare clases (incluyendo abstractas y todos los dems tipos de clases), interfaces y
enumerados, y hacer un uso apropiado de las sentencias "package" e "import".

Cuando escribimos cdigo en Java, escribimos clases o interfaces. Dentro de las clases, como ya sabemos, estn
las variables y los mtodos ( y alguna otra cosa ms). Como declaremos nuestras clases, mtodos y variables
afecta dramticamente la conducta del cdigo. Por ejemplo un mtodo pblico puede ser accedido desde cdigo
ejecutado fuera de nuestra aplicacin, mientras que uno privado no. Por este motivo, debemos estudiar la
manera de declarar y modificar (o no) una clase.

Antes de adentrarnos en las declaraciones de clases, vamos a hacer un rpido repaso a las normas asociadas con
la declaracin de clases, y el uso de sentencias import y package en el cdigo fuente.
Cada fichero cdigo fuente debe tener una sola clase pblica.
Los comentarios pueden aparecer en cualquier lnea de cdigo.
Si hay una clase pblica en un fichero, el nombre del fichero debe coincidir con el nombre de la clase
pblica.
Si la clase pertenece a un paquete, la sentencia "package" debe estar en la primera lnea de cdigo, antes
de cualquier sentencia "import" que haya.
Si hay sentencias "import", deben estar entre la sentencia "package" (si hay) y la declaracin de la clase.
No hay manera de declarar mltiples clases en un fichero y que tengan diferentes paquetes, o usen
diferentes sentencias "import".
Un fichero puede tener ms de una clase no pblica.
Un fichero que no tenga clase pblica puede tener cualquier nombre, no debe coincidir con el nombre de
ninguna de las clases que contiene.

En el Capitulo 10 - Desarrollo, veremos con ms detalle las normas implicadas en la declaracin y uso de
sentencias package e import, y una nueva caracterstica de Java 5, "static import".

3.1. Declaraciones y modificadores de Clases

El siguiente cdigo es la declaracin de una clase:
class myClass {}

Este cdigo compila bien, pero se le pueden aadir modificadores antes de la declaracin de la clase. Los
modificadores se dividen en dos categoras:
Modificadores de acceso (public, protected y private):
Sirven para restringir o permitir el acceso a una clase creada. El control de acceso de Java es un poco difcil
porque hay cuatro niveles de acceso pero solo tres modificadores de acceso. El cuarto nivel de acceso ( por
defecto) es cuando no utilizamos ninguno de los tres modificadores de acceso. En otras palabras, que toda clase,
mtodo y variable declarada tiene un control de acceso, indiques el tipo explcitamente o no. Aunque todos los
controles de acceso funcionan para la mayora de mtodos y declaraciones de variables, una clase solo puede ser
declarada como publica o por defecto; los otros dos niveles de acceso no tienen sentido para una clase, como a
continuacin veremos.
Java es un lenguaje centrado en paquete; los desarrolladores asumieron que para una buena organizacin y
mbito de nombres, se debera meter todas las clases en paquetes. Ellos tenan razn, y deberamos imaginarnos
la siguiente pesadilla: Tres programadores de la misma compaa trabajan en diferentes partes de un proyecto,
escriben una clase llamada utilities . Si estas tres clases no estn declaradas en ningn paquete explicito, y estn
en el classpath, tu no tendrs ninguna forma de decirle al compilador o JVM a cul de las tres clases estn
intentando hacer referencia. Sun recomienda que los desarrolladores usen nombres de dominio invertidos, junto
con alguna divisin y/o nombres de proyecto. Por ejemplo: Si el nombre de tu dominio es
geeksanonymous.com, y t estas trabajando en el cdigo del cliente para el programa TwelvePointOSteps, t
deberas nombrar tu paquete algo parecido a com.geeksanonymous.steps.client. De esta forma deberas cambiar
el nombre de tu clase a com.geeksanonymous.steps.client.Utilities. Es posible que an tengas conflicto de
nombres en tu propia compaa, si t no sigues con tu propio esquema de nombres, pero con esto consigues no
colisionar con clases desarrolladas en otras compaas.

Acceso a clases

Cuando queremos que una clase A tenga acceso a otra clase B, la clase A debe hacer un de las siguientes tres
cosas:
Crear una instancia de la clase B
Extender de la clase B
Acceso seguro a mtodos y variables de la clase B, dependiendo del control de acceso de estos mtodos
o variables.

En efecto, el acceso se conoce como visibilidad. Si la clase A no puede ver a la clase B, el nivel de acceso a los
mtodos y variables dentro de la clase B no tiene importancia; la clase A no tiene ninguna manera de acceder a
estos mtodos y variables.


Acceso por defecto
Una clase con acceso por defecto no tiene modificador precedindola en la declaracin. El nivel de acceso por
defecto es a nivel de paquete, es decir una clase con acceso por defecto solo es vista por las clases de su mismo
paquete. Por ejemplo si la clase A y la clase B estn en diferentes paquetes, y la clase A tiene un nivel de acceso
por defecto, la clase B no tiene permitido crear una instancia de la clase A, o incluso declarar una variable o
devolver un tipo de clase A. De hecho, la clase B tiene que fingir que la clase A no existe, o el compilador se
quejara. Mira el siguiente cdigo:
package cert;
class Beverage { }

Ahora mira este siguiente cdigo:
package exam.stuff;
import cert.Beverage;
class Tea extends Beverage { }

Como podemos ver , la superclase (Beverage) est en un paquete diferente de la subclase (Tea). La sentencia
import del fichero Tea est intentando importar la clase Beverage. El fichero Beverage compila bien, pero
cuando intentamos compilar la clase Tea obtendremos algo parecido a:

Can't access class cert.Beverage. Class or interface must be public, in same package, or an accessible member
class. import cert.Beverage;

La clase Tea no puede compilar porque su superclase, Beverage, tiene acceso por defecto y est en un paquete
diferente. Como solucin a este problema podemos hacer dos cosas:
Poner las clases en el mismo paquete
Poner la clase Beverage como public (lo veremos a continuacin)
Cuando veamos una pregunta con lgica compleja, nos debemos asegurar de mirar primero los modificadores
de acceso. De esta forma, si encontramos una violacin de acceso (por ejemplo una clase del paquete A que
intenta acceder a una por defecto del paquete B), sabrs que el cdigo no compilara, as que no pierdas el
tiempo en la lgica y elige la opcin "fallo de compilacin" y vete a la siguiente pregunta.

Acceso pblico "public"

Todas las clases del universo Java tienen acceso a una clase pblica. No olvides, que si una clase publica que
estas intentando usar se encuentra en un diferente paquete en el cual se encuentra la clase que estamos
escribiendo, deberemos importar la clase pblica.

En el ejemplo que vimos anteriormente, es posible que no quiera guardar la subclase en el mismo paquete que la
superclase. Para hacer que el cdigo funcione, necesitamos aadir la palabra clave public en la declaracin de la
superclase, como se muestra a continuacin:
package cert;
public class Beverage { }




Este cambio hace visible a la clase para todas las clases en todos los paquetes. La clase puede ser ahora
instanciada desde cualquier otra clase, y cualquier clase puede extender de ella, a menos que tambin este
marcada con el modificador de no_acceso "final".

Modificadores de no-acceso (incluyendo strictfp, final y abstract)

Podemos cambiar la declaracin de una clase usando las palabras clave "final", "abstract" o "strictfp". Estos
modificadores son adicionales a cualquier control de acceso de la clase. Por ejemplo: declarar una clase como
public y final. Pero no siempre podemos mezclar modificadores de no acceso. Por ejemplo podemos usar una
combinacin de final y strictfp, pero nunca marcar una clase como final y abstract.
Para el examen, solo necesitamos saber que "strictfp" es una palabra clave y puede ser usada para modificar una
clase o un mtodo, pero nunca una variable. Marcando una clase como "strictfp" significa que cualquier cdigo
de mtodo de la clase ser conforme a las estndar de normas IEEE 754 para puntos flotantes. Sin este
modificador, los puntos flotantes usados en los mtodos podran comportarse de una forma dependiente de la
plataforma. Si t no declaras una clase como "strictfp", an puedes conseguir un comportamiento "strictfp"
mtodo a mtodo.

Clases Final

Cuando usamos la palabra clave "final" en la declaracin de una clase, ninguna clase puede extender de la clase
final, y cualquier intento de hacerlo le dar un error de compilacin.
Solo se debe marcar una clase como final si necesitamos total garanta de que ninguno de los mtodos de la
clase ser sobrescrito.
Muchas clases en las libreras Java son finales. Por ejemplo, la clase String no puede ser extendida por ninguna
otra clase. Imagine que no pudisemos garantizar como trabaja un objeto String
Un beneficio de tener clases no finales sera el siguiente: Imagine encontrar un problema en el mtodo de una
clase que est usando, pero no tiene el cdigo fuente. De esta forma no podemos modificar el cdigo para
mejorar el mtodo, pero si puedes extender de la clase y sobrescribir los mtodos en tu nueva subclase y
sustituir la subclase en todos los sitios donde apareca la superclase.
Vamos a modificar nuestro ejemplo Beverage para marcar al mtodo como final:
package cert;
public final class Beverage {
public void importantMethod() { }
}

Ahora, si intentamos compilar la subclase Tea
package exam.stuff;
import cert.Beverage;
class Tea extends Beverage { }

Nosotros obtendremos algo parecido a lo siguiente:

Can't subclass final classes: class
cert.Beverage class Tea extends Beverage{
1 error

En la prctica, casi nunca vamos a crear una clase final. Una clase final elimina un beneficio clave de la
programacin orientada a objetos (extensibilidad, que otras clases extiendan de otra). Por lo tanto, al menos que
necesitemos mucha seguridad, asume que algn da otro programador necesitara extender de tu clase.

Clases Abstractas
Una clase abstracta nunca ser instanciada. Su nico objetivo es ser extendida (que otra clase extienda de ella).
(NOTA, sin embargo, t puedes compilar y ejecutar una clase abstracta, siempre y cuando t no intentes
instanciarla). Porque hacer una clase si no podemos hacer objetos fuera de ella?. Debido a que la clase puede
ser demasiado abstracta. Por ejemplo, imagina que tienes una clase Car que tiene mtodos comunes con todos
los vehculos. Pero t no quieres que nadie cree un objeto abstracto Car genrico. Lo que necesitas es instanciar
tipos de coche como BMWBoxster y Subaruoutback. Eche un vistazo a la siguiente clase abstracta:

abstract class Car {
private double price;
private String model;
private String year;
public abstract void goFast();
public abstract void goUpHill();
public abstract void impressNeighbors();
// Additional, important, and serious code goes here
}


Este cdigo compilara bien. Pero si intentamos instanciar un Car in otra cdigo, el compilador nos dar un error
de compilacin similar al siguiente:
AnotherClass.java:7: class Car is an abstract
class. It can't be instantiated.
Car x = new Car();
1 error

NOTA: Los mtodos marcados abstractos acaban en ";" y no en llaves "{}".

Nosotros veremos los mtodos abstractos con ms detalle despus en este objetivo, pero recordar que siempre
que haya un mtodo abstracto en una clase, esa clase debe ser marcada como abstracta. Un mtodo abstracto
spoils the whole bunch .Pero, sin embargo, podemos poner mtodos no abstractos en una clase abstracta. Por
ejemplo: tu necesitaras tener mtodos con implementaciones que no deberan cambiar de un tipo de Car a otro,
tales como "getColor()" o "setPrice". Por poner mtodos abstractos en una clase abstracta, las subclases de la
clase abstracta heredan mtodos implementados. La buena noticia es que las subclases heredan funcionalidad, y
necesitan implementar solo los mtodos que definen el comportamiento especfico de la subclase.
Codificando con tipos de clases abstractas permite obtener ventajas de polimorfismo y dar un mayor grado de
flexibilidad y extensibilidad. Aprenderemos ms sobre polimorfismo en el Polimorfismo.
No podemos marcar una clase como abstracta y final. Porque tienen significados opuestos, una clase abstracta
debe ser extendida por otras clases mientras que una final no tendr clases que extiendan de ella. Si vemos una
combinacin de estos modificadores, usados para la declaracin de un mtodo o clase, el cdigo no compilara.

4. Objetivo de Certificacin 1.2 - Declarar Interfaces

Desarrollar cdigo que declare una interfaz. Desarrollar cdigo que implemente o extienda de una o ms
interfaces. Desarrollar cdigo que declare una clase abstracta. Desarrollar cdigo que extienda de una clase
abstracta.
4.1. Declaracin de una interfaz
Cuando creas una interfaz, estas definiendo un contrato de lo que la clase podr hacer, sin decir nada sobre
como lo har.
Las interfaces pueden ser implementadas por cualquier clase, desde cualquier rbol de herencia. Esto te permite
tomar clases diferentes y darles una caracterstica comn. Por ejemplo, la clase Baln y la clase Neumtico
tienen Botar como comportamiento, pero Baln y Neumtico no comparten ninguna relacin de herencia (Baln
extiende de Juguete y Neumtico de java.lang.Object). Pero haciendo que ambas clases implementen la interfaz
Botable (del verbo botar), estaremos diciendo que ambos pueden ser tratados como, "Cosas que pueden botar",
que en el lenguaje Java significa "Cosas que pueden invocar los mtodos botar() y setBotarFactor()". La
siguiente figura muestra la relacin entre interfaces y clases.



Una interfaz define mtodos abstractos que toman la siguiente forma:
abstract void bounce(); // Ends with a semicolon rather than
// curly braces

Parece que son iguales una interfaz que una clase abstracta, pero no es as. Mientras una clase abstracta puede
definir tanto mtodos abstractos como no abstractos, una interfaz solo puede tener mtodos abstractos. Otra
manera de diferenciar las interfaces de las clases abstractas es que las interfaces tienen muy poca flexibilidad en
como los mtodos y variables definidas en la interfaz son declaradas. Las siguientes normas son estrictas:
Todos los mtodos de una interfaz son implcitamente pblicos y abstractos.
Todas las variables definidas en una interfaz deben ser pblicas, estticas y finales, en otras palabras, las
interfaces solo pueden declarar constantes, no instancias de variables.
Los mtodos de una interfaz no deben ser estticos.
Debido a que los mtodos de una interfaz sin abstractos, no pueden ser marcados como final, strictfp o
nativo
Una interfaz puede extender de una o ms interfaces.
Una interfaz no puede extender de cualquier cosa excepto de una interfaz.
Una interfaz no puede implementar otra interfaz o clase.
Una interfaz debe ser declarada con la palabra clave "interface".
Los tipos de interfaz pueden ser usados polimrficamente (ver capitulo 2 Polimorfismo para ms
detalle.)
A continuacin mostraremos una declaracin legal de una interfaz:
public abstract interface Rollable { }

Las interfaces son implcitamente abstractas, se considera redundante mrcala como abstracta. Solo debemos
saber que las dos siguientes declaraciones son legales:
public abstract interface Rollable { }
public interface Rollable { }

El modificador "public" es requerido si deseas que la interfaz sea pblica y no tenga un nivel de acceso por
defecto.
A continuacin mostramos como se declaran los mtodos de una interfaz.

public interface Bounceable {
public abstract void bounce();
public abstract void setBounceFactor(int bf);
}

Marcar los mtodos con los modificadores public y abstract es redundante, ya que todos los mtodos de una
interfaz son implcitamente public y abstract. Veremos a continuacin como el cdigo siguiente es equivalente
al anterior:
public interface Bounceable {
void bounce(); // No modifiers
void setBounceFactor(int bf); // No modifiers
}

Los siguientes cinco mtodos declarados con una combinacin de modificadores public, abstract o no
modificadores son legales e idnticos.
void bounce();
public void bounce();
abstract void bounce();
public abstract void bounce();
abstract public void bounce();

Las siguientes declaraciones de mtodos de una interfaz no pueden compilar:
final void bounce(); // final and abstract can never be used
// together, and abstract is implied
static void bounce(); // interfaces define instance methods
private void bounce(); // interface methods are always public
protected void bounce(); // (same as above)

4.2. Declarando constantes de interfaz

Tienes permitido poner constantes en una interfaz. Al hacerlo, garantizas que ninguna clase que implemente la
interfaz tendr acceso a la constante.
Colocando las constantes de forma correcta en una interfaz, cualquier clase que implemente la interfaz tendr
acceso directo a las constantes, como si la clase la heredara.
Tu necesitas recordar una regla clave para las constantes de interfaz. Siempre deben ser "public static final".
NOTA Puesto que las constantes de interfaz son definidas en una interfaz, no tienen que ser declaradas como
public, static *o* final. Siempre son public, static *y* final. Cualquier variable definida en una interfaz debe ser
(e implicitamente lo es) una constante. Mira a ver si puedes encontrar el problema con el siguiente cdigo
(asume que estan en ficheros separados):

interface Foo {
int BAR = 42;
void go();
}

class Zap implements Foo {
public void go() {
BAR = 27;
}
}

Tu no puedes cambiar el valor de una constante! Una vez que el valor haya sido asignado, el valor nunca puede
ser modificado. La asignacion de la constante sucede en la propia interfaz ( donde es declarada), asi la clase que
implementa la interfaz puede acceder a ella y usarla , pero como solo lectura. Asi que la asignacin BAR = 27
no compilara.

5. Declarar miembros de una clase
Los mtodos e instancias de variables son conocidos normalmente como miembros. Podemos modificar un
miembro con ambos modificadores de acceso y no acceso, y tenemos mas modificadores a elegir y combinar,
que cuando declarbamos una clase.

5.1. Modificadores de acceso
Donde una clase puede usar dos de los cuatro niveles de control de acceso (por defecto y public), los miembros
pueden usarlos todos (los cuatro):
public
protected
private
default
La proteccin por defecto es cuando tu no indicas en la declaracin del mtodo ningn tipo de modificador de
acceso. El control de acceso por defecto y protected tienen casi el mismo comportamiento, excepto una
diferencia que comentaremos mas tarde.
Es crucial entender los dos diferentes tipos de acceso:
El primer tipo de acceso es cuando un mtodo de una clase intenta acceder al mtodo o a la variables de
otra clase, usando el operador punto (.) para invocar una metodo o recuperar una variable. Por ejemplo:

class Zoo {
public String coolMethod() {
return "Wow baby";
}
}
class Moo {
public void useAZoo() {
Zoo z = new Zoo();
// If the preceding line compiles Moo has access
// to the Zoo class
// But... does it have access to the coolMethod()?
System.out.println("A Zoo says, " + z. coolMethod());
// The preceding line works because Moo can access the
// public method
}
}
El segundo tipo de acceso es cuando una clase hereda los miembros de otra clase. Para este caso
debemos recordar, que si una clase hereda un miembro, la subclase tiene dicho miembro. Por ejemplo:
class Zoo {
public String coolMethod() {
return "Wow baby";
}
}
class Moo extends Zoo {
public void useMyCoolMethod() {
// Does an instance of Moo inherit the coolMethod()?
System.out.println("Moo says, " + this.coolMethod());
// The preceding line works because Moo can inherit the
// public method
// Can an instance of Moo invoke coolMethod() on an
// instance of Zoo?
Zoo z = new Zoo();
System.out.println("Zoo says, " + z.coolMethod());
// coolMethod() is public, so Moo can invoke it on a Zoo
//reference
}
}

La siguiente figura compara una clase heredando y accediendo usando una referencia al miembro de otra clase.



Muchos de los acceso de control se centran en mirar si las dos clases involucradas estn en el mismo o en o
diferente paquete. No olvidar, sin embargo, que si la clase A en si no puede ser accedida por la clase B,
entonces no hay miembros de la clase A que puedan ser accedidos por la clase B.

Debemos saber el efecto de diferentes combinaciones de acceso de clases y miembros ( tal como una clase por
defecto con una variable publica). Primero debemos mirar el nivel de acceso de la clase. Si la clase en si no es
visible a otras clase, entonces ninguno de los miembros, aunque sea public, sera visible tampoco. Una vez
hayamos confirmado que la clase es visible, entonces debemos mirar el nivel de acceso individual de cada
miembro.

5.2. Miembros Public
Cuando un miembro es declarado public significa que todas las clases, independientemente del paquete al que
pertenezca, pueden acceder al miembro (asumiendo que la clase es visible).
Mira el siguiente cdigo:
package book;
import cert.*; //Import all classes in the cert package
class Goo {
public static void main(String[] args) {
Sludge o = new Sludge();
o.testIt();
}
}

Ahora mira las siguientes lineas:
package cert;
public class Sludge {
public void testIt() { System.out.println("sludge"); }
}

Como podemos ver, Goo y Sludge se encuentran en diferentes paquetes. Sin embargo, Goo puede invocar al
mtodo testIt() en Sludge sin problemas debido a que la clase Sludge y el mtodo testIt() son pblicos.

Desde una subclase, si un miembro de la superclase es declarado pblico, la subclase hereda esos miembros
independientemente de si estn o no en el mismo paquetes las clases.
package cert;
public class Roo {
public String doRooThings() {
//imagine the fun code that goes here
return "fun";
}
}

La clase Roo declara el miembro doRooThings() como pblico. As que si nosotros creamos una subclase de
Roo, cualquier cdigo de la subclase pueda llamar a su propio mtodo doRooThings() heredado.
package notcert;// Not the package Roo is in
import cert.Roo;
class Cloo extends Roo {
public void testCloo() {
System.out.println(doRooThings());
}
}

Mira en el cdigo anterior como el mtodo doRooThings() es invocado sin necesidad de tener una referencia.
Recuerda, si tu ves un mtodo invocado (o una variable accedida) sin el operador punto (.), sabrs que el
mtodo o la variable pertenecen a la clase donde estas viendo el cdigo. Tambin sabrs que el mtodo o la
variable estn siendo implcitamente accedidos usando la referencia this. As que en el cdigo anterior, la
llamada a doRooThings() en la clase Cloo podra haberse escrito tambin como this.doRooThings(). La
referencia this siempre se refiere al actual objeto en ejecucin, en otras palabras, el cdigo donde tu ves la
referencia this.

Ademas de ser capaz de invocar al mtodo doRooThings() por si misma, el cdigo de alguna otra clase puede
llamar a doRooThings() con una instancia de Cloo, como en el siguiente:
class Toon {
public static void main(String[] args) {
Cloo c = new Cloo();
System.out.println(c.doRooThings()); //No problem; method//
is public
}
}




5.3. Miembros privados

Los miembros marcados como "private" no pueden ser accedidos por cdigo desde cualquier clase distinta de la
clase en la que el miembro es declarado. Vamos a hacer un pequeo cambio a la clase Roo de un ejemplo
anterior:
El mtodo doRooThings() es ahora privado, asi que ninguna otra clase puede usarlo. Si nosotros intentamos
invocar al mtodo desde cualquier otra clase, tendremos problemas al ejecutar:
package notcert;
import cert.Roo;
class UseARoo {
public void testIt() {
Roo r = new Roo(); //So far so good; class Roo is public
System.out.println(r.doRooThings());// Compiler error!
}
}

Si nosotro intentamos compilar UseARoo, nosotros obendremos un error del compilador parecido al siguiente:

cannot find symbol
symbol : method doRooThings()

Es como si el mtodo no existiera. Un miembro privado es invisible a cualquier cdigo fuera de los propios
miembros de la clase.
Cuando un miembro es declarado privado, una subclase no puede heredarlo. Para el examen, necesitamos
reconocer que una subclase no puede ver o usar el miembro privado de la superclase. Podemos sin embargo,
declarar un mtodo similar en la subclase. Pero independientemente de como se vea, no es un mtodo
sobrescrito. Es simplemente un mtodo que resulta tener el mismo nombre que un mtodo privado ( que tu no
sabias nada de el) de la superclase. Las reglas de sobrescritura no se aplican, asi que puedes hacer con el mtodo
lo que quieras.

package cert;
public class Roo {
private String doRooThings() {
//imagine the fun code that goes here, but no other class//
will know
return "fun";
}
}

El mtodo doRooThings()esta ahora fuera de limites para todas las subclase, incluso los que estan en el mismo
paquete como la superclase:
package cert; //Cloo and Roo are in the same package
class Cloo extends Roo {// Still OK, superclass Roo is public
public void testCloo() {
System.out.println(doRooThings()); //Compiler error!
}
}

Si nosotros intentamos compilar la subclase Cloo, el compilador mostrara algo parecido a lo siguiente:

%javac Cloo.java
Cloo.java:4: Undefined method: doRooThings()
System.out.println(doRooThings());
1 error

NOTA: Aunque tengamos permitido marcar instancias de variables como publicas, en la practica es mejor
marcarlas como private o protected. Si las variables necesitan ser cambiadas, o ledas , los programadores
deberan usar mtodos de acceso pblicos para acceder a ellas. Asi que el cdigo en cualquier otra clase tiene
que llamar al get o set de la variable, en lugar de acceder a ella directamente. Los mtodos de acceso toman la
forma get (para booleanos is) y set, y proporcionan un lugar donde verificar y validar antes de devolver o
modificar el valor.

Un mtodo privado no puede ser sobrescrito por una subclase. Desde la subclase, como hemos visto, no
podemos heredar un mtodo privado, por lo tanto no puede sobrescribir al mtodo. En la siguiente figura
veremos los efectos de los modificadroes private y public en clases desde el mismo o diferente paquete:





5.4. Miembros protected o default

Los niveles de control de acceso protected y por defecto son casi idnticos, pero con una diferencia. Un
miembro con control de acceso por defecto debe ser accedido solo si la clase que esta accediendo esta dentro
del mismo paquete, sin embargo un miembro protected puede ser accedido por una subclase aunque estn en
diferentes paquetes.
Mira las siguientes dos clases en diferentes ficheros:
package certification;
public class OtherClass {
void testIt() { //No modifier means method has default//
access
System.out.println("OtherClass");
}
}

package somethingElse;
import certification.OtherClass;
class AccessClass {
static public void main(String[] args) {
OtherClass o = new OtherClass();
o.testIt();
}
}

El compilador devolver algo parecido a:

No method matching testIt() found in class
certification.OtherClass. o.testIt();

El comportamiento del control de acceso por defecto y el protected difiere solo cuando hablamos de subclases.
Si la palabra protected es usada para definir un miembro, cualquier subclase de la clase declarando el miembro
puede acceder a el a travs de la herencia. No nos tenemos que fijar si las clases estn en diferentes paquetes, el
miembro protected de la superclase es visible a la subclase (aunque visible solo en un caso muy especifico
como veremos mas adelante). Hay una diferencia con el comportamiento que tendra si lo declarsemos como
por defecto, ya que no permite a una subclase acceder al miembro de una superclase a menos que la subclase
este en el mismo paquete que la superclase.
NOTA: Cuando pienses en acceso por defecto, piensa entonces en la restriccin de paquetes.
Pero cuando tu pienses en el tipo de acceso protected, piensa en las restricciones de paquetes e hijos.
Una clase con un miembro protected tiene marcado que el miembro tiene acceso a nivel de paquete para todas
las clases del paquete, pero con una excepcin para las subclases fuera del paquete que heredaria el mtodo. No
significa, sin embargo, no significa que la subclase fuera del paquete pueda acceder al miembro usando una
referencia a una instancia de la superclase. En otras palabras, protected = herencia. Protected no significa que la
subclase pueda tratar al miembro protected de la superclase como si fuera public. As que si la subclase fuera
del paquete obtiene una referencia de las superclase ( creando la instancia en cualquier lugar del cdigo de la
subclase), la subclase no puede usar el operador punto para acceder a un miembro protected de la superclase.
Para una subclase un mtodo protected significara lo mismo que si fuese por defecto ( o incluso private),
cuando la subclase use una referencia a la superclase. La subclase puede ver al miembro protected solo a travs
de la herencia.

Detalles de proteted

Vamos a hechar un vistazo a la instancia de la variable protected de una superclase.
package certification;
public class Parent {
protected int x = 9; //protected access
}

El cdigo anterior declara la variable x como protected. Esto hace a la variable accesible para todas las otras
clases dentro del mismo paquete, y tambien heredable para cualquier subclase fuera del paquete. Ahora vamos a
crear una subclase en un paquete diferent e intentaremos usar la variable x (que la subclase herdara):
package other;// Different package
import certification.Parent;
class Child extends Parent {
public void testIt() {
System.out.println("x is " + x); //No problem; Child//
inherits x
}
}

El anterior cdigo compila bien. Vemos como la clase hijo esta accediendo a la variable protected a travs de la
herencia. Recordar, que cuando hablamos de que una subclase tiene acceso al miembro de una superclase, nos
referimos a que la subclase hereda el miembrp, pero no accediendo al miembro a travs de una referencia
mediante una instancia de la superclase. A continuacin, mostraremos que sucederia en el caso de acceder a una
variable protected usando una referencia a la clase Parent:
package other;
import certification.Parent;
class Child extends Parent {
public void testIt() (
System.out.println("x is " + x); //No problem; Child//
inherits x
Parent p = new Parent(); //Can we access x using the//
p reference?
System.out.println("X in parent is " + p.x); //Compiler//
error!
}
}

El compilador mostraria lo siguiente:

%javac -d . other/Child.java
other/Child.java:9: x has protected access in certification.Parent
System.out.println("X in parent is " + p.x);
^
1 error

Hasta el momento tenemos establecido que un miembro protected tiene acceso a nivel de paquete o por defecto,
a todas las clases excepto a las subclases. Hemos visto que las subclase fuera del paquete pueden heredar un
miembro protected. Para terminar, hemos visto que las subclase fuera del paquete no pueden usar una referencia
a la superclase para acceder a un miembro protected. Para una subclase fuera del paquete, el miembro protected
solo puede ser accedido a travs de herencia.

An queda algunas cosas que mirar de los miembros protected. Que sudecera si una nueva clase del mismo
paquete que la subclase intenta acceder a travs de una referencia de dicha subclase a la variable protected x?,
en otras palabras cual seria el comportamiento del miembro protected una vez la subclase lo haya heredado?.
Una vez la subclase fuera del paquete hereda el miembro protected, dicho miembro (como heredado de la
subclase) se convierte en private para cualquier cdigo fuera de la subclase, con excepcin de las subclases de
la subclase.

Detalles del acceso por defecto

Vamos a empezar con el comportamiento del acceso por defecto de un miembro en una superclase. Nosotros
modificaremos el miembro x de Parent para hacerlo por defecto.
package certification;
public class Parent {
int x = 9; //No access modifier, means default//
(package) access
}

Ahora intentaremos acceder al miembro con acceso por defecto desde la clase Child de antes:
Cuando nosotros compilamos obtenemos un error similar a este:


Child.java:4: Undefined variable: x
System.out.println("Variable x is " + x);
1 error


El compilador da el mismo error que cuando el miembro es declarado private. La subclase Child (en un paquete
diferente del de la suoerclase Parent) no puede ver o usar el miembro con acceso por defecto x de la superclase.
Que pasaria ahora si estuviesen en el mismo paquete?
package certification;
public class Parent{
int x = 9; //default access
}

Y en la segunda clase tu tienes lo siguiente:
package certification;
class Child extends Parent{
static public void main(String[] args) {
Child sc = new Child();
sc.testIt();
}
public void testIt() {
System.out.println("Variable x is " + x);// No problem;
}
}

El cdigo anterior compila bien, y la clase Child ejecutara y mostrara el valor de x. Recordar que un miembro
con acceso por defecto es visible por una subclase solo si esta en el mismo paquete que la superclase.



5.5. Variables locales y Modificadores de acceso

Hay una variable local no se le puede aplicar modificadores de acceso, como por ejemplo se ve en el siguiente
cdigo:
class Foo {
void doStuff() {
private int x = 7;
this.doMore(x);
}
}

Tu puedes estar seguro que cualquier variable local declarada con un modificador de acceso no compilara. De
hecho, solo el modificador final puede ser aplicado a una variable local. La siguiente tabala nos muestra todas
las combinaciones de acceso y visibilidad:
Visibilidad Public Protected Default Private
Desde la misma clase si si si si
Desde cualquier clase en el mismo paquete si si si no
Desde una subclase en el mismo paquete si si si no
Desde una clase fuera del paquete si si, a travs de herencia no no
Desde cualquier clase no subclase fuera del paquete si no no no




5.6. Modificadores de no acceso en miembros

Ya estamos un poco familiarizado con algunos modificadores de no acceso como pueden ser final y abstract que
los vimos en la declaracin de clases anteriormente en este capitulo. Pero todava nos queda dar un repaso
rpido a transient, syncronized, native, strictfp y mas extendido veremos el modificador static.
Primero veremos los modificadores aplicados a mtodos, seguidamente veremos los modificadores aplicados a
instancias de variable. Y por ultimo acabaremos con la forma de trabajar del modificador static en variables y
mtodos.



5.7. Mtodos final

La palabra clave final previene a un mtodo de ser sobrescrito en una subclase, y se hace a menudo para
cumplir la funcionalidad del mtodo. Por ejemplo, la clase Thread tiene un mtodo llamado isAlive() que
comprueba si un hilo esta activo. Si tu extiendes la clase Thread, no hay forma de que tu puedas implementar
ese mtodo, ya que el diseador la marco como final. Debemos tener cuidado a la hora de utilizarlo, ya que
previenes que una subclase sobrescriba un mtodo y con esto quitamos muchos beneficios de la Orientacin a
Objetos como la extensibilidad. La declaracin de un mtodo final tipica es parecida a la siguiente:
class SuperClass{
public final void showSample() {
System.out.println("One thing.");
}
}

Es legal extender extender a Superclass, ya que la clase no esta marca como final, pero no podremos
sobrescribir el mtodo final showsample(), como el siguiente cdigo intenta hacer.
class Subclass extends SuperClass{
public void showSample() { //Try to override the final//
superclass method
System.out.println("Another thing.");
}
}

Al intentar compilar el cdigo anterior, el compilador nos dar algo parecido a esto:

%javac FinalTest.java
FinalTest.java:5: The method void showsample() declared in class
Subclass cannot override the final method of the same signature
declared in class SuperClass.
Final methods cannot be overridden.
public void showSample() { }
1 error


Argumentos final

Los argumentos de un mtodo son las declaraciones de variables que aparecen entre los parntesis en la
declaracin del mtodo. Una declaracin tpica de mtodo con mltiples argumentos es parecido a lo siguiente:
public Record getRecord(int fileNumber, int recordNumber) {}

Los argumentos de un mtodo son esencialmente lo mismo que variables locales. En el ejemplo anteior, ambas
variables fileNumber y recordNumber siguen las reglas aplicadas a las variables locales. Esto significa que
pueden tambin tener el modificador final:
public Record getRecord(int fileNumber, final int recNumber) {}

En este ejemplo, la variable recordNumbre es declarada final, que significa que no podremos modificarla dentro
del mtodo. En este caso, "modificado" significa reasignarle un nuevo valor a la variable. En otras palabras, un
argumento final debe mantener el mismo valor que tuvo cuando fue pasado al mtodo.



5.8. Mtodos abstract

Un mtodo abstracto es un mtodo que esta declarado pero no implementado. En otras palabras, el mtodo no
contiene ningn cdigo que realice alguna funcionalidad. Y si tu recuerdas la seccin que hemos visto en este
capitulo de clases abstractas, la declaracin de un mtodo abstracto no lleva llaves ({}) donde va la
implementacin del cdigo si no que termina con punto y coma (;). En otras palabras el mtodo no tiene cuerpo.
Tu marcas un mtodo abstracto cuando quieres forzar a las subclases a que lo implementen. Por ejemplo, si tu
escribes una clase abstracta Car con un mtodo abstracto goUpHill(), debes querer forzar a cada subtipo de Car
a definir el comportamiento propio de goUpHill():
public abstract void showSample();

Fjate como el mtodo abstracto termina con punto y coma (;) y no con llaves ({}). Es ilegal incluso tener un
solo mtodo abstracto en una clase que no esta declarada explicitamente como abstract. Mira la siguiente clase
que es ilegal:
public class IllegalClass{
public abstract void doIt();
}

La clase anterior producir el siguiente error si intentas compilarla:

IllegalClass.java:1: class IllegalClass must be declared
abstract.
It does not define void doIt() from class IllegalClass.
public class IllegalClass{
1 error


Tu puedes, sin embargo, tener una clase abstracta sin ningn mtodo abstracto. El siguiente ejemplo compilaria
bien:
public abstract class LegalClass{
void goodMethod() {
//lots of real implementation code here
}
}

En el ejemplo anterior, goodMethod() no es abstracto. A continuacin veremos tres formas diferentes de ver que
un mtodo no es abstracto:
El mtodo no esta marcado como abstract.
La declaracin del mtodo incluye llaves, en vez de terminar con punto y coma (;). En otras palabras, el
mtodo tiene cuerpo.
El mtodo tiene cdigo.

Cualquier clase que extienda de una clase abstracta debe implementar todos los mtodos abstractos de la
superclase, a menos que la subclase sea tambin abstracta. La reglas es la siguiente:

La primera subclase que no sea abstracta de una clase que si es abstracta debe implementar todos los mtodos
abstractos de la superclase.

El siguiente cdigo nos muestra un arbol de herencia con dos clases abstractas y una que no lo es.
public abstract class Vehicle {
private String type;
public abstract void goUpHill();// Abstract method
public String getType() { //Non-abstract method
return type;
}
}

public abstract class Car extends Vehicle {
public abstract void goUpHill();// Still abstract
public void doCarThings() {
//special car code goes here }
}
}

public class Mini extends Car {
public void goUpHill() {//
Mini-specific going uphill code
}
}

Como podemos ver la clase Mini tendr tres mtodos, los mtodos heredados getType() y doCarThings(),
puesto que son pblicos y no abstractos. Pero ya que goUpHill() es abstracto en la superclase Vehicle, y nunca
es implementado en la clase Car, significa que la clase Mini (primera clas no abstracta despues de Vehicle) debe
implementar el mtodo goUpHill(). En otras palabras, la clase Mini no puede pasar la implementacin del
mtodo abstracto a la prxima clase del rbol de herencia por debajo, pero la clase Car si puede porque es
abstracta.
La siguiente imagen nos muestra los efectos del modificador abstract en subclases abstractas y no abstractas.



Las clases no abstractas que no proporciones implementacin a los mtodos abstractos de la superclase no
compilarn como podemos ver en el siguiente cdigo:
public abstract class A {
abstract void foo();
}
class B extends A {
void foo(int I) { }
}

La clase B no compilara porque no implementa el mtodo abstracto heredado foo(). Aunque el mtodo foo(int I)
en la clase aparenta ser una implementacin del mtodo abstracto de la superclase, es simplemente un mtodo
sobrecargado (un mtodo usando el mismo identificador, pero con diferentes argumentos), as que no cumple
los requerimientos de implementacin del mtodo abstracto de la superclase. Nosotros veremos la diferencia
entre sobrecargado y sobrescrito con mas detalle en el Cpitulo 2 Polimorfismo.
Un mtodo nunca puede, con los modificadores abstract y final, o abstract y private. Piensa que los mtodos
abstractos deben ser implementado (que significa sobrescrito por una subclase) sin embargo final y private no
pueden ser sobrescritos por una subclase. En otras palabras, cuando declaramos abstract significa que la
superclase no sabe nada sobre como las subclases se comportaran en este mtodo, sin embargo cuando
declaramos final significa que la superclase sabe todo sobre como todas las subclases deben comportarse con
este mtodo. Los modificadores abstract y final son virtualmente opuestos.
Finalmente, necesitas saber que el modificador abstract nunca puede ser combinado con el modificado static.
Mas adelante cubriremos mas los mtodos estticos, pero por ahora recordar que lo siguiente es ilegal:e illegal:
abstract static void doStuff();

El error que nos saldra seria algo parecido a los siguiente:
//MyClass.java:2: illegal combination of modifiers: abstract and
static
abstract static void doStuff();//




5.9. Mtodos syncronized

La palabra clave syncronized indica que un mtodo puede ser accedido por solo un hilo a la vez. Mas adelante
en el Capitulo 11 lo veremos mas detallado, pero por ahora lo que necesitamos saber es que el modificador
syncronized puede ser aplicado solo en mtodos y no en variables ni clase. Una declaracin tipica de
syncronized es la siguiente:
public synchronized Record retrieveUserInfo(int id) { }

Tambin deberamos saber que el modificador syncronized puede ser encontrado con los cuatro nivel de control
de acceso (significa que puede ser emparejado con cualquiera de los tres modificadores de acceso).



5.10. Mtodos Native

El modificador native indica que un mtodo esta implementado en otro lenguaje, el mas comn en C. No
necesitamos saber como usar mtodos nativos para el examen, lo que debemos saber es que es un modificador
(por tanto palabra clave) y que native puede ser solo aplicado en mtodos no en clase ni variables. Otra cosa que
deberamos saber es que el cuerpo de los mtodos native debe ser un punto y coma (;) (como los abstract),
indicando que la implementacin sea omitida.



5.11. Mtodos Strictf
Anteriormente en este capitulo usamos Strictfp como modificador de una clase, pero incluso si no declaramos
una clase como Strictfp, an podemos declarar un mtodo individual como Strictfp. Recordar, strictfp fuerza a
los puntos flotantes a cumplir el estndar IEEE 754. Con strictfp, puedes predecir como actuarn los puntos
flotantes independientemente de la plataforma en la que se este ejecutando la JVM. El problema es que si la
plataforma sobre la que corre la JVM es capaz de soportar gran precisin, un mtodo strictfp sera capaz de
tomar ventaja de eso.
Para el examen no necesitamos saber nada sobre strictfp, solo que puede ser modificador de una clase o mtodo
y que nunca podra ser declarado con una variable.



5.12. Mtodos con lista de argumentos variable (var-args)

Java permite crear mtodos que puedan tomar un nmero variable de argumentos. Nosotros usaremos el termino
"var-args".
A continuacin nos gustara clarificar como vamos a usar los trminos argumento y parmetro en el resto de la
documentacin:
Argumentos Lo que declaramos entre los parntesis cuando invocamos a un mtodo:

doStuff("a", 2); //invoking doStuff, so a & 2 are arguments

Parmetros Lo que debe recibir el mtodo cuando es invocado.

void doStuff(String s, int a) { }// we're expecting two
//parameters: String and int

Nosotros trataremos los mtodos que usan un nmero variable de argumentos, por ahora vamos a revisar las
reglas de declaracin de var-args:
Tipo de var-arg Cuando declaramos un parmetro var-arg, debemos especificar el tipo de argumento/s
que podemos recibir (puede ser un tipo primitivo o un objeto).
Sintaxis bsica Al declarar un mtodo usando un parmetro var-arg, continuaremos el tipo con una
elipsis (...), un espacio y entonces el nombre del array recibir el parmetro recibido.
Otros parmetros Es legal tener otros parmetros en un mtodo que usa var-arg.
Limites de var-args Debe ser el ultimo parmetro en la declaracin del mtodo, y puedes tener un solo
var_arg en el mtodo.

Vamos a ver a continuacin algunas declaraciones legales e ilegales:

Legales:
void doStuff(int... x) { }// expects from 0 to many ints
//as parameters
void doStuff2(char c, int... x) { }// expects first a char,
//then 0 to many ints
void doStuff3(Animal... animal) { }// 0 to many Animals

Ilegales:
void doStuff4(int x...) { } //bad syntax
void doStuff5(int... x, char... y) { }// too many var-args
void doStuff6(String... s, byte b) { } //var-arg must be last



5.13. Declaracin de constructores

En Java, los objetos estn construidos. Cada vez que queremos crear un nuevo objeto, necesitamos invocar a su
constructor. Todas las clases tienen un constructor, si tu no creas uno explicitamente, el compilador construir
uno para ti. Hay muchas reglas concernientes a los constructores, trataremos esto en ms profundidad en el
captulo 2. Por ahora, nos vamos a enfocar en las reglas bsicas de declaracin. Aqu un ejemplo simple:
class Foo {
protected Foo() { }// this is Foo's constructor

protected void Foo() { } //this is a badly named,//
but legal, method
}

Lo primero que vemos es que los constructores son como mtodos. Una diferencia clave es que un constructor
nunca tiene un tipo return. Las declaraciones de constructores pueden tener todos los modificadores de acceso
normal y pueden tomar argumentos (incluyendo var-args), como los mtodos. La otra GRAN REGLA que
tenemos que entender de los constructores es que deben ser llamados como la clase en la que son declarados.
Los constructores no pueden ser marcados como static (estn asociados con instanciaciones de objeto), nunca
pueden ser marcados final o abstract (porque no pueden ser sobrescritos). A continuacin veremos
declaraciones de constructores legales e ilegales:
class Foo2 {

//constructores legales

Foo2() { }
private Foo2(byte b) { }
Foo2(int x) { }
Foo2(int x, int... y) { }

//constructores ilegales

void Foo2() { } //it's a method, not a constructor
Foo() { }// not a method or a constructor
Foo2(short s); //looks like an abstract method
static Foo2(float f) { }// can't be static
final Foo2 (long x) { } //can't be final
abstract Foo2 (char c) { }// can't be abstract
Foo2 (int... x, int t) { } //bad var-arg syntax
}




5.14. Declaraciones de Variable
Hay dos tipos de variable en Java:
Primitivas Un primitivo puede ser uno de los ocho tipos: char, boolean, byte, short, int, long, double o
float. Una vez el primitivo haya sido declarado, ese tipo primitivo nunca cambia, aunque en su mayoria
de los casos cambia de valor.
Variables de referencia Una variable de referencia es usado para referirse (o acceder) a un objeto. Una
referencia esta declarada para ser de un tipo especifico y nunca puede cambiar. Una referencia puede ser
usada para referirse a cualquier tipo especifico, o de un subtipo del tipo declarado (un tipo compatible).
Hablamos mas de esto en el captulo 2, cuando discutimos polimorfismo.



5.15. Declarando primitivos y Rangos de primitivos

Las variables primitivas pueden ser declaradas comom variables de clase (estaticas), instancias de variables,
parametros de mtodos o variables locales. Puedes declarar uno o mas primitivos, del mismo tipo de primitivo,
en una sola linea. En el captulo 3 discutiremos las diferentes maneras en la que pueden ser inicializados, pero
por ahora solo veremos un pequeo ejemplo de declaraciones de variables:
byte b;
boolean myBooleanPrimitive;
int x, y, z;// declare three int primitives

En versiones anteriores del examen necesitabas saber como calcular los rangos para todos los tipo primitivos.
Para el examen actual, puedes pasar de alguno de los detalles, pero an es importante entender que para los
tipos entero la secuencia de menor a mayor es: byte, short, int, long y que doubles son mayor que floats
Tambin necesitaras saber que los tipos de nmero son todos con signo y que les afecta sus rangos. Primero
vamos a revisar los conceptos.

Todos los seis tipos en Java estan hechos de un nmero de 8-bit bytes y son son signo, significa que pueden ser
negativos y positivos. El bit mas significativo (bit mas a la izquierda) es usado para representar el signo, donde
un 1 significa negativo y 0 positivo, como se muestra en la siguiente figura. El resto de los bits representa el
valor, usando notacin complemento a 2.



A continuacin mostraremos los tipos primitivos con sus tamaos y rangos.
Tipo Bits Bytes Minimo Maximo
byte 8 1 -27 27-1
short 16 2 -215 215-1
int 32 4 -231 231-1
long 64 8 -263 263-1
float 32 4 n/a n/a
double 64 8 n/a n/a

El rango de los nmeros en punto flotante es complicado de determinar, pero afortunadamente no necesitamos
saberlo para el examen (aunque se espera que sepamos que un double tiene 64 bits y un flota 32 bits).

Para los tipos booleanos no hay un rango, un booleano solo puede ser true o false.

el tipo char (un carcter) contiene un nico carcter, 16bits Unicode. Los caracteres Unicode son actualmente
representados por enteros sin signo de 16 bits, que significa 216 valores posibles, rango desde 0 a 65535 (216)-
1. El porque un carcter es realmente un tipo entero lo entenders mejor en el Capitulo 3, pueden ser asignados
a cualquier nmero lo suficientemente largo hasta llegar a tener 65535. Aunque el char y el short son tipos de
16 bits, recordar que un short usa 1 bit para representar al signo, as que pocos nmeros positivos son aceptables
en un short.



5.16. Declaracin de Variables de Referencia
Las variables de referencia pueden ser declaradas como variables estticas, instancias de variables, parmetros
de mtodo o variables locales. Puedes declarar una o mas referencias, del mismo tipo, en una sola linea. En el
capitulo 3 discutiremos las diferentes maneras en que pueden ser inicializadas, pero por ahora vamos a ver unos
cuantos ejemplos de declaraciones de variables de referencia:
Object o;
Dog myNewDogReferenceVariable;
String s1, s2, s3; declare three String vars.



5.17. Variables de instancia
Las variables de instancia estn definidas en la clase, pero fuera de cualquier mtodo, y son inicializadas solo
cuando la clase es instanciada. Las variables de instancia son los campos que pertenecen a cada objeto nico.
Por ejemplo, el siguiente cdigo define campos (variables de instancia) para el nombre, ttulo y manager de los
objetos empleados:
class Employee {
//define fields (instance variables) for employee instances
private String name;
private String title,

private String manager;
//other code goes here including access methods for private
//fields
}

La clase Empleado puede decir que cada instancia de empleado sabr su propio nombre, ttulo y manager. En
otras palabras, cada instancia puede tener sus propios valores nicos de los tres campos. Si tu ves los trminos
campo, variables de instancia, propiedad o atributo, todas virtualmente significan lo mismo.
Para el examen, necesitamos saber que las variables de instancia:
Pueden usar cualquiera de los cuatro niveles de acceso(que significa que pueden ser marcados con
cualquiera de los tres modificadores de acceso).
Pueden ser marcados con final.
Pueden ser marcados con transient.
No pueden ser marcados abstract.
No pueden ser marcados syncronized.
No pueden ser marcados strictfp.
No pueden ser marcados native.
No pueden ser marcados static, por que si no serian variables de clase.

Tenemos que abarcar los efectos de aplicacin de controles de acceso a variables de instancia (trabajan de la
misma forma que para los mtodos). Un poco despus en este captulo explicaremos que significa aplicar el
modificador final o transient a una variable de instancia. Primero veremos cual es la diferencia entre una
variable de instancia y una variable local. La siguiente tabla compara la manera en que los modificadores
pueden ser aplicados a mtodos vs variables.
Variables
locales
Variables no locales Mtodos
final
final public protected private static
transient volatile
final public protected private static abstract
synchronized strictfp native



5.18. Variables locales (Automtica/Pila/Mtodo)

Las variables locales estn declaradas dentro de un mtodo. Esto significa que la variable no esta inicializada
dentro del mtodo. Ya que la variable local empieza su vida dentro del mtodo, es tambin destruida cuando el
mtodo sea completado. Las variables locales estn siempre en la pila, no en la heap. Aunque el valor de la
variable debe ser pasado a otro mtodo entonces almacenara el valor en una variable de instancia, la variable
por si sola vive solo dentro del mbito del mtodo.
No olvidar que la variable esta en la pila, si la variable es un objeto referencia, el objeto an sera creado en la
heap. No hay una pila de objeto, solo una pila de variable.
Las declaraciones de variables locales no pueden usar mas tipos de modificadores que pueden ser aplicados a
una variable de instancia, como public (o los otros modificadores de acceso), transient, volatile, abstract o static,
pero como vimos anteriormente las variables locales pueden ser marcadas final. Esto lo veremos mas en el
Captulo 3 pero por ahora debemos saber que una variable local antes de poder ser usada, debe ser inicializada
con un valor.
Class TestServer {
public void logIn() {
int count = 10;
}
}

Normalmente inicializaremos una variable local en la misma linea en que la declaras, aunque puede que an sea
necesario reinicializarla ms tarde en el mtodo. La clave es que una variable local debe ser in inicializada antes
de intentar usarla.El compilador rechazara cualquier cdigo que intente usar una variable local que no tenga
asignado un valor, porque a diferencia de las variables de instancia, las variables locales no obtienen valores por
defecto.
Una variable local no puede estar referenciada en cualquier cdigo fuera del mtodo en que esta declarada. En
el anterior cdigo de ejemplo, seria imposible referenciar a la variable count desde cualquier otro lugar de la
clase excepto dentro del mbito del mtodo logIn(). Como veremos en el siguiente cdigo ilegal:
class TestServer {
public void logIn() {
int count = 10;
}
public void doSomething(int i) {
count = i; //Won't compile! Can't access count outside//
method login()
}
}

Es posible declarar una variable local con el mismo nombre que una variable de instancia. Conocida como
shadowing, como lo demuestra el siguiente cdigo:
class TestServer {
int count = 9; //Declare an instance variable named count
public void logIn() {
int count = 10;// Declare a local variable named count
System.out.println("local variable count is " + count);
}
public void count () {
System.out.println("instance variable count is " + count);
}
public static void main(String[] args)

new TestServer().logIn();
new TestServer().count();
}
}

El anterior cdigo produce la siguiente salida:


local variable count is 10
instance variable count is 9


El siguiente cdigo (incorrecto) esta intentando cambiar el valor de la variable de instancia usando un
parametro:
class Foo {
int size = 27;
public void setSize(int size) {
size = size; //??? que size es igual a que size???
}
}

Para resolver esto tenemos la palabra clave this. Con this siempre, siempre nos vamos a referir al objeto
actualmente en ejecucin. El siguiente cdigo muestraa this es accin:
class Foo {
int size = 27;
public void setSize(int size) {
this.size = size;// this.size means the current object's
//instance variable, size. The size//
on the right is the parameter
}
}



5.19. Declaracin de Array
En Java, los arrays son objetos que almacenan mltiples variables del mismo tipo, o variables que son subclases
del mismo tipo. Los Arrays pueden tener tanto primitivos como referencias a objetos, pero pero el propio array
siempre es un objeto en la heap, incluso si el array es declarado para tener elementos primitivos. En otras
palabras,
Para el examen tenemos tres cosas que sabernos:
Como crear un array como variable de referencia (declarar).
Como crear un objeto array (constructor).
Como rellenar el array con elementos (inicializar).

Para este objetivo, solo necesitas saber como declarar un array, nosotros cubriremos la construccin e
inicializacin en el Capitulo 3.

Nota de trabajo:
Los arrays son eficientes, pero muchas veces queremos usar un tipo Collection de java.util (incluye HashMap,
ArrayList y TreeSet). Las clases Collection ofrecen mayor flexibilidad de acceso al objeto (para insercin,
borrado, lectura y muchas mas) y es diferente a los arrays, pueden expandir y contraer a medida que aadimos o
elimninamos elementos. Hay un tipo de Collection para cada necesidad, por ejemplo, si necesitamos una rapida
ordenacin, un grupo de objetos que no se dupliquen, almacenar parejas clave/valor...Esto lo veremos con mas
detalle en el cpitulo 7.
Los arrays son declarados indicando el tipo de elementos que el array contendra (objeto o primitivo), seguido de
corchetes a cada lado del identificador.

Declarando un array de primitivos
int[] key; //Square brackets before name (recommended)
int key [];// Square brackets after name (legal but less
//readable)

Declarando un array de Objetos referencias.
Thread[] threads;// Recommended
Thread threads []; //Legal but less readable

Nota para el trabajo:
Cuando declaramos una referencia array, deberiamos poner siempre los corchetes inmediatamente despues del
tipo declarado, en lugar de despues del identificador (nombre variable). De esta forma, nadie leyendo el cdigo
puede facilmente decir por ejemplo, clave es una referencia a un objeto array de enteros, y no un tipo entero
primitivo.
Podemos tambien declarar arrays multidimensionales, que son en realidad arrays de arrays. Esto se puede hacer
de la siguiente manera.
String[][][] occupantName;
String[] ManagerName [];

El primer ejemplo es un array tridimensional y el segundo es bidimensional. Fijate como en el segundo ejemplo
nosotros tenemos unos corchetes antes del nombre de la variable y otros despus. Esto es perfectamente legal
para el compilador, demostrando una vez ms que por que sea legal no significa que sea correcto.

Exam Watch

Nunca es legal incluir el tamao del array en su declaracin. Si, nosotros sabemos que puede hacerse en otros
lenguajes, que es la razn por la que puede ver una o dos preguntas que incluya cdigo similar al siguiente:
int[5] scores;

El cdigo anterior no compilara. Recordar, la JVM no asigna el espacio hasta que se instancia al objeto array.
Que es cuando realmente importa su tamao.


En el Captulo 3, nosotros pasaremos mucho tiempo discutiendo de arrays, como inicializarlos y usarlos, y
mostrar con detalle los arrays multidimensionales.



5.20. Variables Finales
Declarando una variable con la palabra final haces que sea imposible reinicializar la variables una vez haya sido
inicializada con un valor explicito (por defecto). Para los primitivos, esto significa que una vez que la variable
tiene asignado el valor, el valor no puede ser alterado. Por ejemplo, si tu asignas 10 a la variable de tipo entero,
entonces la x va a permanecer a 10, siempre. Una variables referenciada marcada como final no puede incluso
ser reasignada para referirse a un objeto diferente. El dato dentro del objeto puede ser modificado, pero la
referencia de la variable no puede ser cambiada. Nos debemos quedar con: no hay objetos finales, solo
referencias finales. Esto se explica con mas detalle en el Captulo 3
Nosotros ahora vamos a ver en la siguiente imagen como el modificador final puede ser aplicado a las clases,
mtodos y variables.

Figure 1-8: Effect of final on variables, methods, and classes



5.21. Variables Transient

Si marcas una instancia de variable como transient, tu le estas diciendo a la JVM que ignore esa variable cuando
trate de serializar al objeto que lo contiene. La serializacin es una de las caracteristicas mas buenas de Java;
permite guardar el valor de su variable instanciada en un tipo especial de flujo de I/O. Con la serializacin tu
puedes guardar un objeto a un fichero y mas cosas que avordaremos mejor en el Captulo 6



5.22. Variables Volatile

El modificador volatile le indica a la JVM que un hilo que acceda a la variable debe siempre conciliar su propia
copia privada de la variable con la copia master en memoria. Para el examen, todo lo que necesitas saber sobre
volatile es que, como con transient, puede ser solo aplicado a variables de instancia. No nos equivoquemos, la
idea de multiples hilos accediendo a una variable de instancia es coda de miedo, y muy importante que lo
entiendan los programadores Java. Pero lo veremos mejor en el Captulo 11, probablemente usaremos
sincronizacin, en lugar del modificador volatile, para hacer tu hilo de datos seguro.
Nota de trabajo:
El modificador volatile debe tambin ser aplicado a proyectos managers.



5.23. Variables y Mtodos estticos
El modificador static es usado para crear variables y mtodos que existirn independientemente de cualquier
instancia creada por la clase. En otras palabras, los miembros static existen antes incluso de crear una nueva
instancia de la clase y habr solo una copia del miembro esttico independientemente del nmero de instancias
de la clase. En otras palabras, todas las instancias de una clase tienen el mismo valor para una variable esttica.
Cubriremos los miembros static en gran detalle en el prximo captulo.
Cosas que podemos marcar como static:
Mtodos.
Variables.
Una clase anidada dentro de otra clase, pero no dentro de un mtodo (ms sobre esto en el Captulo 8)
Bloques de inicializacin

Cosas que no podemos marcarlas static:
Constructores (hacerlo no tiene sentido, un constructor es usado solo para crear instancias).
Clases (a menos que estn anidadas)
Interfaces
Mtodos locales dentro de clases (lo veremos mas en detalle en el Captulo 8)
Mtodos dentro de clases y variables de instancia.
Variables locales.



5.24. Declarando enumerados (enum)
A partir de Java 5.0, permite restringir a una variable a tener solo uno pocos valores predefinidos, en otras
palabras, un valor de una lista enumerada
Usando enumerados podemos ayudar a reducir los bugs en el cdigo. Por ejemplo, en tu aplicacin "cofee shop"
tu debes querer restringir tu seleccin de tamaos a "BIG", "HUGE" y "OVERWHELMING". Si tu dejas que
un pedido sea "LARGE" o "GRANDE" debera causar un error. Enums al rescate. Con la siguiente declaracin
simple, tu puedes garantizar que el compilador te impedir la asignacin de otro tipo de CoffeeSize excepto
BIG, HUGE o OVERWEHLMING:
enum CoffeeSize { BIG, HUGE, OVERWHELMING };

A partir de entonces, la nica manera de obtener un CoffeeSize sera con una sentencia como la siguiente:
CoffeeSize cs = CoffeeSize. BIG;

No es necesario que las constantes enumeradas esten todas en mayusculas, pero tomando prestada las
convenciones de cdigo de Sun que las constantes van en mayusculas, es una buena idea.
Los componentes bsicos de un enumerado son constantes, aunque dentro de poco veras que puede haber
muchas mas cosas en un enumerado. Los enumerados pueden ser declarados como una clase propia separada, o
como una clase miembro, sin embargo no deben ser declaradas dentro de un mtodo.

Declarando un enumerado fuera de una clase
enum CoffeeSize { BIG, HUGE, OVERWHELMING }// this cannot be
//private or protected

class Coffee {
CoffeeSize size;
}

public class CoffeeTest1 {
public static void main(String[] args) {
Coffee drink = new Coffee();
drink.size = CoffeeSize.BIG;// enum outside class
}
}

El cdigo anterior puede ser partido en un solo fichero. ( Recordar, el fichero debe ser llamado CoffeeTest1.java
ya que este es el nombre de la clase publica en el fichero. El punto clave a recordar es que los enumerados
pueden ser declarado solo con los modificadores public o default, al igual que una clase no interna. Aqui el
ejemplo de un enumerado declarado dentro de una clase.
class Coffee2 {
enum CoffeeSize {BIG, HUGE, OVERWHELMING }

CoffeeSize size;
}

public class CoffeeTest2 {
public static void main (String[] args) {
Coffee2 drink = new Coffee2();
drink.size = Coffee2.CoffeeSize.BIG; //enclosing class//
name required
}
}

Los puntos claves a tomar de estos ejemplos son que los enumerados pueden ser declrados como una clase
propia o encerrados en otra clase, y que la sintaxis para acceder al miembro de un enumerado depende de donde
el enumerado fue declarado.
Lo siguiente no es legal:
public class CoffeeTestl {
public static void main(String[] args) {
enum CoffeeSize { BIG, HUGE, OVERWHELMING } //WRONG! Cannot//
declare enums
//in methods
Coffee drink = new Coffee();
drink.size = CoffeeSize.BIG;
}
}

Para hacerlo todo mas confuso, los diseadores del lenguaje Java han puesto opcional poner un punto y coma (;)
al final de la declaracin de un enumerado.
public class CoffeeTest1 {

enum CoffeeSize { BIG, HUGE, OVERWHELMING };// <--semicolon
//is optional here
public static void main(String[] args) {
Coffee drink = new Coffee();
drink.size = CoffeeSize.BIG;
}
}

Lo mas importante que debemos recordar es que los enumerados no son String ni ints. Cada tipo de los
enumerados CoffeeSize son actualmente instancias de CoffeeSize. En otras palabras, BIG es de tipo CoffeeSize,
Piensa de un enumerado como una especie de clase, es algo parecido a esto (pero no exactamente):
//conceptual example of how you can think//
about enums

class CoffeeSize {
public static final CoffeeSize BIG =
new CoffeeSize("BIG", 0);
public static final CoffeeSize HUGE =
new CoffeeSize("HUGE", 1);
public static final CoffeeSize OVERWHELMING =
new CoffeeSize("OVERWHELMING", 2);

public CoffeeSize(String enumName, int index) {//
stuff here
}
public static void main(String[] args) {
System.out.println(CoffeeSize.BIG);
}
}

Fjate como cada uno de los valores de los enumerados son instancias del tipo CoffeeSize. Ellos estn
representados como static y final, que en el mundo Java, es como si fuera una constante. Fjate tambin como
cada valor del enumerado sabe su indice o posicin, en otras palabras, el orden en el que los enumerados son
declarados. Tu puedes pensar de los enumerados de CoffeeSize como si existieran en un array de tipo
CoffeeSize y veremos en un capitulo mas adelante como puedes iterar sobre los valores de un enumerado
invocando al mtodo values() en cualquier tipo enumerado.

Declarando constructores, mtodos y variables en un Enumerado
Dado que un enumerado realmente es un tipo especial de clase, puedes hacer algo mas que la lista de valores
constantes enumerados. Puedes aadir constructores, variables de instancia, mtodos y algo realmente extrao
como una constante especifica del cuerpo de la clase. Para entender porque tu necesitas mas en tu enumerado,
imaginate este escenario: quieres saber el actual tamao, en onzas, de cada una de las tres constantes
CoffeeSize. Por ejemplo, tu quieres saber que BIG tiene 8 onzas, HUGE 10 onzas y OVERWHELMING 16
onzas.
Podrias hacer algn tipo de tabla, usando alguna otra estructura de datos pero seria un mal diseo y duro
mantenimiento. La forma mas simple es tratar a los valores de los enumerados como objetos que pueden tener
cada uno su propia variables de instancia. Entonces tu puedesasignar esos valores a la vez que inicalizas los
enumerados, pasandole un valor al constructor del enumerado. Vamos a ver el siguiente cdigo:
enum CoffeeSize {

BIG(8), HUGE(10), OVERWHELMING(16);
//the arguments after the enum value are "passed"//
as values to the constructor

CoffeeSize(int ounces) {

this.ounces = ounces; //assign the value to//
an instance variable
}

private int ounces; //an instance variable each enum//
value has
public int getOunces() {
return ounces;
}
}

class Coffee {
CoffeeSize size; //each instance of Coffee has-a//
CoffeeSize enum

public static void main(String[] args) {
Coffee drink1 = new Coffee();
drinkl.size = CoffeeSize.BIG;

Coffee drink2 = new Coffee();
drink2.size = CoffeeSize. OVERWHELMING;

System.out.println(drinkl.size.getOunces()); //prints 8
System.out.println(drink2.size. getOunces());// prints 16
}
}

Los puntos claves a recordar sobre los constructores de enumerados son:
Nunca puedes invocar directamente el constructor de un enumerado. El constructor de un enumerado es
invocado automaticamente, con los argumentos tu defines el valor de la constante.Por ejemplo BIG(8)
invoca al constructor de CoffeeSize que toma un valor int, pasandole el valor 8.
The key points to remember about enum constructors are
Puedes definir mas de un argumento para el constructor y sobrecargar los constructores de enumerados,
al igual que puedes sobrecargar un constructor de una clase normal. Discutiremos mas sobre los
constructores en el Captulo 2.

Y finalmente, puedes definir algo realmente extrao en un enumerado que se ve como una clase interna
anonima (de la cual hablaremos en el captulo 8). Se conoce como una constante especifica del cuerpo de una
clase y se usa cuando necesitas una constante particular para anular un mtodo definido en el enumerado.
And finally, you can define something really strange in an enum that looks like an anonymous inner class
(which we talk about in Chapter 8). It's known as a constant specific class body, and you use it when you need a
particular constant to override a method defined in the enum.
Parece extrao pero necesitas entender las reglas bsicas de declaracin:
enum CoffeeSize {
BIG(8),
HUGE(10),
OVERWHELMING(16) { //start a code block that defines//
the "body" for this constant

public String getLidCode() { //override the method//
defined in CoffeeSize
return "A";
}
}; //<-- the semicolon is REQUIRED when you have a body

CoffeeSize(int ounces) {
this.ounces = ounces;
}

private int ounces;

public int getOunces() {
return ounces;
}
public String getLidCode() {// this method is overridden
//by the OVERWHELMING constant

return "B";// the default value we want to return for//
CoffeeSize constants
}
}

También podría gustarte