martes, 23 de octubre de 2012

Operadores


Operadores

Los operadores realizan algunas funciones en uno o dos operandos. Los operadores que requieren un operador se llaman operadores unarios. Por ejemplo, ++ es un operador unario que incrementa el valor su operando en uno.

Los operadores que requieren dos operandos se llaman operadores binarios. El operador = es un operador binario que asigna un valor del operando derecho al operando izquierdo.

Los operadores unarios en Java pueden utilizar la notación de prefijo o de sufijo. La notación de prefijo significa que el operador aparece antes de su operando:
operador operando

La notación de sufijo significa que el operador aparece después de su operando:
operando operador

Todos los operadores binarios de Java tienen la misma notación, es decir aparecen entre los dos operandos:
op1 operator op2

Además de realizar una operación también devuelve un valor. El valor y su tipo dependen del tipo del operador y del tipo de sus operandos. Por ejemplo, los operadores aritméticos (realizan las operaciones de aritmética básica como la suma o la resta) devuelven números, el resultado típico de las operaciones aritméticas. El tipo de datos devuelto por los operadores aritméticos depende del tipo de sus operandos: si sumas dos enteros, obtendrás un entero. Se dice que una operación evalúa su resultado.
Es muy útil dividir los operadores Java en las siguientes categorías: aritméticos, relacionales y condicionales. Lógicos y de desplazamiento y de asignación.

Operadores Aritméticos
El lenguaje Java soporta varios operadores aritéticos - incluyendo + (suma), - (resta), * (multiplicación), / (división), y % (módulo)—en todos los números enteros y de coma flotante. Por ejemplo, puedes utilizar este código Java para sumar dos números:
sumaEsto + aEsto
O este código para calcular el resto de una división:
divideEsto % porEsto

Esta tabla sumariza todas las operaciones aritméticas binarias en Java:

Operador       Uso                 Descripción
+                      op1 + op2       Suma op1 y op2
-                      op1 - op2        Resta op2 de op1
*                      op1 * op2       Multiplica op1 y op2
/                      op1 / op2         Divide op1 por op2
%                     op1 % op2     Obtiene el resto de dividir op1 por op2

Nota: El lenguaje Java extiende la definición del operador + para incluir la concatenación de cadenas.
Los operadores + y - tienen versiones unarias que seleccionan el signo del operando:
Operador       Uso Descripción
+                      + op Indica un valor positivo
-                      - op Niega el operando

Además, existen dos operadores de atajos aritméticos, ++ que incrementa en uno su operando, y -- que decrementa en uno el valor de su operando.

Operador       Uso          Descripción
++                   op ++      Incrementa op en 1; evalúa el valor antes de incrementar
++                    ++ op     Incrementa op en 1; evalúa el valor después de incrementar
--                     op --       Decrementa op en 1; evalúa el valor antes de decrementar
--                     -- op       Decrementa op en 1; evalúa el valor después de decrementar

Operadores Relacionales y Condicionales
Los valores relacionales comparan dos valores y determinan la relación entre ellos. Por ejemplo, != devuelve true si los dos operandos son distintos.
Esta tabla sumariza los operadores relacionales de Java:

Operador                   Uso                 Devuelve true si
>                             op1 > op2             op1 es mayor que op2
>=                          op1 >= op2           op1 es mayor o igual que op2
<                             op1 < op2             op1 es menor que op2
<=                          op1 <= op2            op1 es menor o igual que op2
==                          op1 == op2            op1 y op2 son iguales
!=                           op1 != op2             op1 y op2 son distintos

Frecuentemente los operadores relacionales se utilizan con otro juego de operadores, los operadores condicionales, para construir expresiones de decisión más complejas. Uno de estos operadores es && que realiza la operación Y booleana. Por ejemplo puedes utilizar dos operadores relacionales diferentes junto con && para determinar si ambas relaciones son ciertas. La siguiente línea de código utiliza esta técnica para determinar si un índice de un array está entre dos límites- esto es, para determinar si el índice es mayor que 0 o menor que NUM_ENTRIES (que se ha definido previamente como un valor constante):
0 < index && index < NUM_ENTRIES

Observa que en algunas situaciones, el segundo operando de un operador relacional no será evaluado. Consideremos esta sentencia:
((count > NUM_ENTRIES) && (System.in.read() != -1))

Si count es menor que NUM_ENTRIES, la parte izquierda del operando de && evalúa a false. El operador && sólo devuelve true si los dos operandos son verdaderos. Por eso, en esta situación se puede determinar el valor de && sin evaluar el operador de la derecha. En un caso como este, Java no evalúa el operando de la derecha. Así no se llamará a System.in.read() y no se leerá un carácter de la entrada estandard.

Aquí tienes tres operadores condicionales:
Operador                   Uso                 Devuelve true si
&&                        op1 && op2          op1 y op2 son verdaderos
||                               op1 || op2            uno de los dos es verdadero
!                                  ! op                   op es falso

El operador & se puede utilizar como un sinónimo de && si ambos operadores son booleanos. Similarmente, | es un sinónimo de || si ambos operandos son booleanos.

Operadores de Desplazamiento
Los operadores de desplazamiento permiten realizar una manipulación de los bits de los datos. Esta tabla sumariza los operadores lógicos y de desplazamiento disponibles en el lenguaje Java:

Operador       Uso                 Descripción
>>               op1 >> op2          desplaza a la derecha op2 bits de op1
<<               op1 << op2          desplaza a la izquierda op2 bits de op1
>>>            op1 >>> op2         desplaza a la derecha op2 bits de op1(sin signo)
&                op1 & op2             bitwise and
|                   op1 | op2              bitwise or
^                 op1 ^ op2              bitwise xor
~                 ~ op bitwise         complemento

Los tres operadores de desplazamiento simplemente desplazan los bits del operando de la izquierda el número de posiciones indicadas por el operador de la derecha. Los desplazamientos ocurren en la dirección indicada por el propio operador. Por ejemplo:

13 >> 1;

Desplaza los bits del entero 13 una posición a la derecha. La representación binaria del número 13 es 1101. El resultado de la operación de desplazamiento es 110 o el 6 decimal. Observe que el bit situado más a la derecha desaparece. Un desplazamiento a la derecha de un bit es equivalente, pero más eficiente que, dividir el operando de la izquierda por dos. Un desplazamiento a la izquierda es equivalente a multiplicar por dos.
Los otros operadores realizan las funciones lógicas para cada uno de los pares de bits de cada operando. La función "y" activa el bit resultante si los dos operandos son 1.
op1     op2     resultado
0          0          0
0          1          0
1          0          0
1          1          1

Supón que quieres evaluar los valores 12 "and" 13:
12 & 13
El resultado de esta operación es 12. ¿Por qué? Bien, la representación binaria de 12 es 1100 y la de 13 es 1101. La función "and" activa los bits resultantes cuando los bits de los dos operandos son 1, de otra forma el resultado es 0. Entonces si colocas en línea los dos operandos y realizas la función "and", puedes ver que los dos bits de mayor peso (los dos bits situados más a la izquierda de cada número) son 1 así el bit resultante de cada uno es 1. Los dos bits de menor peso se evalúan a 0 porque al menos uno de los dos operandos es 0:

 1101
&    1100
------
 1100


El operador | realiza la operación O inclusiva y el operador ^ realiza la operación O exclusiva. O inclusiva significa que si uno de los dos operandos es 1 el resultado es 1.
op1     op2     resultado
0          0          0
0          1          1
1          0          1
1          1          1

O exclusiva significa que si los dos operandos son diferentes el resultado es 1, de otra forma el resultado es 0:
op1     op2     resultado
0          0          0
0          1          1
1          0          1
1          1          0

Y finalmente el operador complemento invierte el valor de cada uno de los bites del operando: si el bit del operando es 1 el resultado es 0 y si el bit del operando es 0 el resultado es 1.

Operadores de Asignación
Puedes utilizar el operador de asignación =, para asignar un valor a otro.
Además del operador de asignación básico, Java proporciona varios operadores de asignación que permiten realizar operaciones aritméticas, lógicas o de bits y una operación de asignación al mismo tiempo.
Específicamente, supón que quieres añadir un número a una variable y asignar el resultado dentro de la misma variable, como esto:

i = i + 2;
Puedes ordenar esta sentencia utilizando el operador +=.
i += 2;
Las dos líneas de código anteriores son equivalentes.
Esta tabla lista los operadores de asignación y sus equivalentes:

Operador       Uso                             Equivale a
+=                    op1 += op2                 op1 = op1 + op2
-=                    op1 -= op2                  op1 = op1 - op2
*=                    op1 *= op2                 op1 = op1 * op2
/=                    op1 /= op2                   op1 = op1 / op2
%=                   op1 %= op2               op1 = op1 % op2
&=                   op1 &= op2                op1 = op1 & op2
|=                    op1 |= op2                    op1 = op1 | op2
^=                    op1 ^= op2                 op1 = op1 ^ op2
<<=                  op1 <<= op2               op1 = op1 << op2
>>=                  op1 >>= op2               op1 = op1 >> op2
>>>=                op1 >>>= op2             op1 = op1 >>> op2
















Variables y Tipos de Datos


Variables y Tipos de Datos

Las variables son las partes importantes de un lenguaje de programación: ellas son las entidades (valores, datos) que actúan y sobre las que se actúa. Una declaración de variable siempre contiene dos componentes, el tipo de la variable y su nombre:

tipoVariable nombre;

Tipos de Variables

Todas las variables en el lenguaje Java deben tener un tipo de dato. El tipo de la variable determina los valores que la variable puede contener y las operaciones que se pueden realizar con ella.
Existen dos categorías de datos principales en el lenguaje Java: los tipos primitivos y los tipos referenciados.
Los tipos primitivos contienen un sólo valor e incluyen los tipos como los enteros, coma flotante, los caracteres, etc... La tabla siguiente muestra todos los tipos primitivos soportados por el lenguaje Java, su formato, su tamaño y una breve descripción de cada uno:




Los tipos referenciados se llaman así porque el valor de una variable de referencia es una referencia (un puntero) hacia el valor real. En Java tenemos los arrays, las clases y los interfaces como tipos de datos referenciados.

Nombres de Variables
Un programa se refiere al valor de una variable por su nombre. Por convención, en Java, los nombres de las variables empiezan con una letra minúscula (los nombres de las clases empiezan con una letra mayúscula).
Un nombre de variable Java:

  1. Debe ser un identificador legal de Java comprendido en una serie de caracteres Unicode. Unicode es un sistema de codificación que soporta texto escrito en distintos lenguajes humanos. Unicode permite la codificación de 34.168 caracteres. Esto le permite utilizar en sus programas Java varios alfabetos como el japonés, el Griego, el Ruso o el Hebreo. Esto es importante para que los programadores puedan escribir código en su lenguaje nativo.
  2. No puede ser el mismo que una palabra clave o el nombre de un valor booleano (true or false).
  3. No deben tener el mismo nombre que otras variables cuyas declaraciones aparezcan en el mismo ámbito.


La regla número 3 implica que podría existir el mismo nombre en otra variable que aparezca en un ámbito diferente.
Por convención, los nombres de variables empiezan por una letra minúscula. Si una variable está compuesta de más de una palabra, como 'nombreDato' las palabras se ponen juntas y cada palabra después de la primera empieza con una letra mayúscula.


lunes, 22 de octubre de 2012

Constructores


Constructores

Todas las clases Java tienen métodos especiales llamados Constructores que se utilizan para inicializar un objeto nuevo de ese tipo. Los constructores tienen el mismo nombre que la clase --el nombre del constructor de la clase Rectangle es Rectangle(), el nombre del constructor de la clase Thread es Thread(), etc...

Java soporta la sobrecarga de los nombres de métodos para que una clase pueda tener cualquier número de constructores, todos los cuales tienen el mismo nombre.
Al igual que otros métodos sobrecargados, los constructores se diferencian unos de otros en el número y tipo de sus argumentos.

Consideremos la clase Rectangle del paquete java.awt que proporciona varios constructores diferentes, todos llamados Rectangle(), pero cada uno con número o tipo diferentes de argumentos a partir de los cuales se puede crear un nuevo objeto Rectangle. Aquí tiene las firmas de los constructores de la clase java.awt.Rectangle:
public Rectangle()
public Rectangle(int width, int height)
public Rectangle(int x, int y, int width, int height)
public Rectangle(Dimension size)
public Rectangle(Point location)
public Rectangle(Point location, Dimension size)

El primer constructor de Rectangle inicializa un nuevo Rectangle con algunos valores por defecto razonables, el segundo constructor inicializa el nuevo Rectangle con la altura y anchura especificadas, el tercer constructor inicializa el nuevo Rectangle en la posición especificada y con la altura y anchura especificadas, etc...

Típicamente, un constructor utiliza sus argumentos para inicializar el estado del nuevo objeto. Entonces, cuando se crea un objeto, se debe elegir el constructor cuyos argumentos reflejen mejor cómo se quiere inicializar el objeto.

Basándose en el número y tipos de los argumentos que se pasan al constructor, el compilador determina cuál de ellos utilizar, Así el compilador sabe que cuando se escribe:
new Rectangle(0, 0, 100, 200);
El compilador utilizará el constructor que requiere cuatro argumentos enteros, y cuando se escribe:
new Rectangle(miObjetoPoint, miObjetoDimension);
Utilizará el constructor que requiere como argumentos un objeto Point y un objeto Dimension.

Cuando escribas tus propias clases, no tienes por qué proporcionar constructores. El constructor por defecto, el constructor que no necesita argumentos, lo proporciona automáticamente el sistema para todas las clases. Sin embargo, frecuentemente se querrá o necesitará proporcionar constructores para las clases.
Se puede declarar e implementar un constructor como se haría con cualquier otro método en una clase. El nombre del constructor debe ser el mismo que el nombre de la clase y, si se proporciona más de un constructor, los argumentos de cada uno de los constructores deben diferenciarse en el número o tipo. No se tiene que especificar el valor de retorno del constructor.
El constructor para esta subclase de Thread, un hilo que realiza animación, selecciona algunos valores por defecto como la velocidad de cuadro, el número de imágenes y carga las propias imágenes:
class AnimationThread extends Thread {
int framesPerSecond;
int numImages;
Image[] images;
AnimationThread(int fps, int num) {
int i;
super("AnimationThread");
this.framesPerSecond = fps;
this.numImages = num;
this.images = new Image[numImages];
for (i = 0; i <= numImages; i++) {
. . .
// Carga las imágenes
. . .
}
}
}

Observa cómo el cuerpo de un constructor es igual que el cuerpo de cualquier otro método -- contiene declaraciones de variables locales, bucles, y otras sentencias.
Sin embargo, hay una línea en el constructor de AnimationThread que no se verá en un método normal--la segunda línea:
super("AnimationThread");
Esta línea invoca al constructor proporcionado por la superclase de AnimationThread--Thread. Este constructor particular de Thread acepta una cadena que contiene el nombre del Thread. Frecuentemente un constructor se aprovechará del código de inicialización escrito para la superclase de la clase.

En realidad, algunas clases deben llamar al constructor de su superclase para que el objeto trabaje de forma apropiada. Típicamente, llamar al constructor de la superclase es lo primero que se hace en el constructor de la subclase: un objeto debe realizar primero la inicialización de nivel superior.

Cuando se declaren constructores para las clases, se pueden utilizar los especificadores de acceso normales para especificar si otros objetos pueden crear ejemplares de sus clases:
private
Ninguna otra clase puede crear un objeto de su clase. La clase puede contener métodos públicos y esos métodos pueden construir un objeto y devolverlo, pero nada más.
protected
Sólo las subclases de la clase pueden crear ejemplares de ella.
public
Cualquiera pueda crear un ejemplar de la clase.
package-access
Nadie externo al paquete puede construir un ejemplar de su clase. Esto es muy útil si se quiere que las clases que tenemos en un paquete puedan crear ejemplares de la clase pero no se quiere que lo haga nadie más.

Controlar el Acceso a los Miembros de la Clase


Controlar el Acceso a los Miembros de la Clase


Uno de los beneficios de las clases es que pueden proteger sus variables y métodos miembros frente al acceso de otros objetos. ¿Por qué es esto importante? Bien, consideremos esto. Se ha escrito una clase que representa una petición a una base de datos que contiene toda clase de información secreta, es decir, registros de empleados o proyectos secretos de la compañía.

Ciertas informaciones y peticiones contenidas en la clase, las soportadas por los métodos y variables accesibles públicamente en su objeto son correctas para el consumo de cualquier otro objeto del sistema. Otras peticiones contenidas en la clase son sólo para el uso personal de la clase. Estas otras soportadas por la operación de la clase no deberían ser utilizadas por objetos de otros tipos. Se querría proteger esas variables y métodos personales a nivel del lenguaje y prohibir el acceso desde objetos de otros tipos.

En Java se puede utilizar los especificadores de acceso para proteger tanto las variables como los métodos de la clase cuando se declaran. El lenguaje Java soporta cuatro niveles de acceso para las variables y métodos miembros: private, protected, public, y, todavía no especificado, acceso de paquete.

La siguiente tabla le muestra los niveles de acceso pemitidos por cada especificador:
Especificador clase subclase paquete mundo
private              X
protected          X          X*            X
public                X          X             X          X
package            X                          X
La primera columna indica si la propia clase tiene acceso al miembro definido por el especificador de acceso. La segunda columna indica si las subclases de la clase (sin importar dentro de que paquete se encuentren estas) tienen acceso a los miembros. La tercera columna indica si las clases del mismo paquete que la clase (sin importar su parentesco) tienen acceso a los miembros. La cuarta columna indica si todas las clases tienen acceso a los miembros.
Observa que la intersección entre protected y subclase tiene un '*' - este caso de acceso particular tiene una explicación en más detalle más adelante.
Echemos un vistazo a cada uno de los niveles de acceso más detalladamente:

Private
El nivel de acceso más restringido es private. Un miembro privado es accesible sólo para la clase en la que está definido. Se utiliza este acceso para declarar miembros que sólo deben ser utilizados por la clase. Esto incluye las variables que contienen información que si se accede a ella desde el exterior podría colocar al objeto en un estado de inconsistencia, o los métodos que llamados desde el exterior pueden ponen en peligro el estado del objeto o del programa donde se está ejecutando. Los miembros privados son como secretos, nunca deben contársele a nadie.
Para declarar un miembro privado se utiliza la palabra clave private en su declaración.
La clase siguiente contiene una variable miembro y un método privados:
class Alpha {
private int soyPrivado;
private void metodoPrivado() {
System.out.println("metodoPrivado");
}
}

Los objetos del tipo Alpha pueden inspeccionar y modificar la variable soyPrivado y pueden invocar el método metodoPrivado(), pero los objetos de otros tipos no pueden acceder. Por ejemplo, la clase Beta definida aquí:
class Beta {
void metodoAccesor() {
Alpha a = new Alpha();
a.soyPrivado = 10; // ilegal
a.metodoPrivado(); // ilegal
}
}
No puede acceder a la variable soyPrivado ni al método metodoPrivado() de un objeto del tipo Alpha porque Beta no es del tipo Alpha.

Si una clase está intentando acceder a una variable miembro a la que no tiene acceso--el compilador mostrará un mensaje de error similar a este y no compilará su programa:
Beta.java:9: Variable iamprivate in class Alpha not accessible from class Beta.
a.iamprivate = 10;                 // ilegal
^
1 error
Y si un programa intenta acceder a un método al que no tiene acceso, generará un error de compilación parecido a este:
Beta.java:12: No method matching privateMethod() found in class Alpha.
a.privateMethod();                // ilegal
1 error

Protected
El siguiente especificador de nivel de acceso es 'protected' que permite a la propia clase, las subclases (con la excepción a la que nos referimos anteriormente), y todas las clases dentro del mismo paquete que accedan a los miembros. Este nivel de acceso se utiliza cuando es apropiado para una subclase da la clase tener acceso a los miembros, pero no las clases no relacionadas. Los miembros protegidos son como secretos familiares - no importa que toda la familia lo sepa, incluso algunos amigos allegados pero no se quiere que los extraños lo sepan.
Para declarar un miembro protegido, se utiliza la palabra clave protected. Primero echemos un vistazo a cómo afecta este especificador de acceso a las clases del mismo paquete.
Consideremos esta versión de la clase Alpha que ahora se declara para estar incluida en el paquete Griego y que tiene una variable y un método que son miembros protegidos:

package Griego;
class Alpha {
protected int estoyProtegido;
protected void metodoProtegido() {
System.out.println("metodoProtegido");
}
}

Ahora, supongamos que la clase Gamma, también está declarada como miembro del paquete Griego (y no es una subclase de Alpha). La Clase Gamma puede acceder legalmente al miembro estoyProtegido del objeto Alpha y puede llamar legalmente a su método metodoProtegido():
package Griego;

class Gamma {
void metodoAccesor() {
Alpha a = new Alpha();
a.estoyProtegido = 10; // legal
a.metodoProtegido(); // legal
}
}

Esto es muy sencillo. Ahora, investiguemos cómo afecta el especificador portected a una subclase de Alpha.
Introduzcamos una nueva clase, Delta, que desciende de la clase Alpha pero reside en un paquete diferente - Latin. La clase Delta puede acceder tanto a estoyProtegido como a metodoProtegido(), pero solo en objetos del tipo Delta o sus subclases. La clase Delta no puede acceder a estoyProtegido o metodoProtegido() en objetos del tipo Alpha. metodoAccesor() en el siguiente ejemplo intenta acceder a la variable miembro estoyProtegido de un objeto del tipo Alpha, que es ilegal, y en un objeto del tipo Delta que es legal. Similarmente, metodoAccesor() intenta invocar a metodoProtegido() en un objeto del tipo Alpha, que también es ilegal:
import Griego.*;
package Latin;
class Delta extends Alpha {
void metodoAccesor(Alpha a, Delta d) {
a.estoyProtegido = 10; // ilegal
d.estoyProtegido = 10; // legal
a.metodoProtegido(); // ilegal
d.metodoProtegido(); // legal
}
}
Si una clase es una subclase o se cuenta en el mismo paquete de la clase con el miembro protegido, la clase tiene acceso al miembro protegido.

Public
El especificador de acceso más sencillo es 'public'. Todas las clases, en todos los paquetes tienen acceso a los miembros públicos de la clase. Los miembros públicos se declaran sólo si su acceso no produce resultados indeseados si un extraño los utiliza.
Aquí no hay secretos familiares; no importa que lo sepa todo el mundo.
Para declarar un miembro público se utiliza la palabra clave public. Por ejemplo,
package Griego;
class Alpha {
public int soyPublico;
public void metodoPublico() {
System.out.println("metodoPublico");
}
}

Reescribamos nuestra clase Beta una vez más y la ponemos en un paquete diferente que la clase Alpha y nos aseguramos que no están relacionadas (no es una subclase) de Alpha:
import Griego.*;
package Romano;
class Beta {
void metodoAccesor() {
Alpha a = new Alpha();
a.soyPublico = 10; // legal
a.metodoPublico(); // legal
}
}
Como se puede ver en el ejemplo anterior, Beta puede inspeccionar y modificar legalmente la variable soyPublico en la clase Alpha y puede llamar legalmente al método metodoPublico().

Acceso de Paquete
Y finalmente, el último nivel de acceso es el que se obtiene si no se especifica ningún otro nivel de acceso a los miembros. Este nivel de acceso permite que las clases del mismo paquete que la clase tengan acceso a los miembros. Este nivel de acceso asume que las clases del mismo paquete son amigas de confianza. Este nivel de confianza es como la que extiende a sus mejores amigos y que incluso no la tiene con su familia.
Por ejemplo, esta versión de la clase Alpha declara una variable y un método con acceso de paquete. Alpha reside en el paquete Griego:
package Griego;
class Alpha {
int estoyEmpaquetado;
void metodoEmpaquetado() {
System.out.println("metodoEmpaquetado");
}
}
La clase Alpha tiene acceso a estoyEmpaquetado y a metodoEmpaquetado().
Además, todas las clases declaradas dentro del mismo paquete como Alpha también tienen acceso a estoyEmpaquetado y metodoEmpaquetado(). Supongamos que tanto Alpha como Beta son declaradas como parte del paquete Griego:
package Griego;
class Beta {
void metodoAccesor() {
Alpha a = new Alpha();
a.estoyEmpaquetado = 10; // legal
a.metodoEmpaquetado(); // legal
}
}
Entonces Beta puede acceder legalmente a estoyEmpaquetado y metodoEmpaquetado().