www.javarevolutions.com Canal YouTube: Java Revolutions Curso

Anuncio
Curso de Programación Básico
Contenido
1. Introducción
2. Características de Java
3. Tipos de datos
3.1 Enteros
3.2 Reales
3.3 Caracteres
3.4 Boolean
4. Cadenas de Caracteres
5. Definición de Variables
6. Operadores
7.Estructura de clases
7.1 Declaración de la clase
7.2 El cuerpo de la clase
7.3 Declaración de atributos
7.4 Tipos de definiciones de las clases
7.5 Private, protected o public
8. Estructura de los métodos
9. Estructuras de control
9.1 if…[else]
9.2 Switch…case…brake…default .
9.3 While
9.4 Do…while
9.5 For
www.javarevolutions.com
Canal YouTube: Java Revolutions
9.6 Break y continue
10. Objetos y herencia
10.1 Creación y referencia a objetos
10.2 this
10.3 super
10.4 interfaces
www.javarevolutions.com
Canal YouTube: Java Revolutions
1. INTRODUCCIÓN
Comenzamos con una serie de notas sobre Java, especialmente para aquellos que quieren
comenzar a conocerlo y usarlo. La idea es dar una guía ordenada para el estudio de este
lenguaje, muy poderoso y de gran coherencia, aunque todavía adolece de algunas limitaciones
que seguramente se irán superando con el tiempo.
Java es un lenguaje originalmente desarrollado por un grupo de ingenieros de Sun, utilizado por
Netscape posteriormente como base para Javascript. Si bien su uso se destaca en el Web, sirve
para crear todo tipo de aplicaciones (locales, intranet o internet).
2. CARACTERÍSTICAS DE JAVA
A continuación haremos una pequeña redacción de las características del lenguaje, que nos
ayudarán a ver para que tipo de problemas está pensado Java:
2.1 Simple
Es un lenguaje sencillo de aprender. Su sintaxis es la de C++ “simplificada”. Los creadores de Java
partieron de la sintaxis de C++ y trataron de eliminar de este todo lo que resultase complicado o
fuente de errores en este lenguaje. La herencia múltiple, la aritmética de punteros, por la
gestión de memoria dinámica (que en Java se elimina de modo transparente para el
programador gracias al recogedor basura) son ejemplos de "tareas complicadas" de C++ y en
Java se han eliminado poco simplificado.
2.2 Orientado a Objetos
Posiblemente sea el lenguaje más orientado a objetos de todos los existentes; en Java todo, a
excepción de los tipos fundamentales de variables (int, char, long...) es un objeto.
2.3 Distribuido
Java está muy orientado al trabajo en red, soportando protocolos como TCP/IP, UDP, HTTP y
FTP. Por otro lado el uso de estos protocolos es bastante sencillo comparandolo con otros
lenguajes que los soportan.
2.4 Robusto
www.javarevolutions.com
Canal YouTube: Java Revolutions
El compilador Java detecta muchos errores que otros compiladores solo detectarían en tiempo
de ejecución o incluso nunca. A esclarecer así por ejemplo " if(a=b) then ... " o " int i; h=i*2; " son
dos ejemplos en los que el compilador Java no nos dejaría compilar este código; sin embargo un
compilador C compilaría el código y generaría un ejecutable que ejecutaría esta sentencia sin dar
ningún tipo de error).
2.5 Seguro
Sobre todo un tipo de desarrollo: los Applet. Estos son programas diseñados para ser ejecutados
en una página web. Java garantiza que ningún Applet puede escribir o leer de nuestro disco o
mandar información del usuario que accede a la página a través de la red (como, por ejemplo, la
dirección de correo electrónico). En general no permite realizar cualquier acción que pudiera
dañar la máquina o violar la intimidad del que visita la página web.
2.6 Portable
En Java no hay aspectos dependientes de la implementación, todas las implementaciones de
Java siguen los mismos estándares en cuanto a tamaño y almacenamiento de los datos.
Esto no ocurre así en C++, por ejemplo. En éste un entero, por ejemplo, puede tener un tamaño
de 16, 32 o más bits, siendo lo única limitación que el entero sea mayor que un short y menor
que un long int. Así mismo C++ bajo UNIX almacena los datos en formato little endian, mientas
que bajo Windows lo hace en big endian. Java lo hace siempre en little edian para evitar
confusiones.
2.7 Arquitectura Neutral
El código generado por el compilador Java es independiente de la arquitectura: podría
ejecutarse en un entorno UNIX, Mac o Windows. El motivo de esto es que el que realmente
ejecuta el código generado por el compilador no es el procesador del ordenador directamente,
sino que este se ejecuta mediante una máquina virtual. Esto permite que los Applets de una web
pueda ejecutarlos cualquier máquina que se conecte a ella independientemente de que sistema
operativo emplee (siempre y cuando el ordenador en cuestión tenga instalada una máquina
virtual de Java).
2.8 Multithread
Soporta de modo nativo los threads, sin necesidad del uso de de librerías específicas (como es el
caso de C++). Esto le permite además que cada Thread de una aplicación java pueda correr en
www.javarevolutions.com
Canal YouTube: Java Revolutions
una CPU distinta, si la aplicación se ejecuta en una máquina que posee varias CPU. Las
aplicaciones de C++ no son capaces de distribuir, de modo transparente para el programador, la
carga entre varias CPU.
3. TIPOS DE DATOS
En Java toda variable declarada ha de tener su tipo, y además antes de poder emplearla hemos
de inicializarla a un valor, si no es compilador se quejará y no generará los archivos .class. Esto
por ejemplo en C no es necesario, siendo fuente de muchos errores al emplearse en operaciones
variables que nos hemos olvidado de inicializar. A continuación pasamos a describir los tipos de
datos:
3.1 Enteros
Almacenan como su propio nombre indica números enteros, sin parte decimal. Cabe destacar,
como ya se indicó en el primer tema, que por razones de portabilidad todos los datos en Java
tienen el mismo tamaño y formato. En Java hay cuatro tipos de enteros:
Tabla 1: tipo de datos enteros en Java
Tipo
Tamaño (bytes)
Rango
Byte
1
-128 a 127
Short
2
-32768 a 32767
Int
4
-2147483648 a 2147483647
-9223372036854775808 a
Long
8
9223372036854775807
Para indicar que una constante es de tipo long lo indicaremos con una L: 23L.
www.javarevolutions.com
Canal YouTube: Java Revolutions
3.2 Reales
Almacenan número reales, es decir números con parte fraccionaria. Hay dos tipos:
Tabla 2: tipos de datos reales en Java
Tipo
Tamaño (bytes)
Rango
Float
4
+ 3.40282347E+38
Double
8
+ 179769313486231570E+308
Si queremos indicar que una constante es flotante: ej: 2.3 hemos de escribir: 2.3F, sino por
defecto será double.
3.3 Caracteres
En Java hay un único tipo de carácter: char. Cada carácter en Java esta codificado en un formato
denominado Unicode, en este formato cada carácter ocupa dos bytes, frente a la codificación en
ASCII, dónde cada carácter ocupaba un solo byte.
Unicode es una extensión de ASCII, ya que éste último al emplear un byte por carácter sólo daba
acogida a 256 símbolos distintos. Para poder aceptar todos los alfabetos (chino, japonés, ruso...)
y una mayor cantidad de símbolos se creó el formato Unicode.
En Java al igual que en C se distingue la representación de los datos char frente a las cadenas de
caracteres. Los char van entre comillas simples: char ch = ‘a’, mientras que las cadenas de
caracteres usan comillas dobles.
3.4 Boolean
www.javarevolutions.com
Canal YouTube: Java Revolutions
Se trata de un tipo de dato que solo puede tomar dos valores: “true” y “false”. Es un tipo de dato
bastante útil a la hora de realizar chequeos sobre condiciones. En C no hay un dato equivalente y
para suplir su ausencia muchas veces se emplean enteros con valor 1 si “true” y 0 si “false”.
Otros lenguajes como Pascal sí tiene este tipo de dato.
4 CADENAS DE CARACTERES
En Java no hay un tipo predefinido para cadenas de caracteres, en su lugar hay una clase, String,
que es la que soporta las distintas operaciones con cadenas de caracteres. La definición de un
String es:
String e ;
//no inicializado
String e =””;
//cadena vacía
String e = “Hola”;
//inicialización y asignación juntas.
A continuación veremos algunas operaciones básicas soportadas por la clase String:
4.1 Concatenación
La concatenación en Java es increíblemente sencilla: se realiza con el operador +, es decir
“sumando” cadenas de caracteres obtenemos la concatenación de estas. Lo ilustraremos con un
ejemplo:
String saludo = “hola”;
String nombre = “Pepe”;
String saluda_pepe = “”;
saluda_pepe = saludo + nombre;// saluda_pepe toma el valor
holaPepe
La sencillez de Java en el manejo de cadenas de caracteres llega incluso más alla: si una cadena
la intentamos encadenar con otro tipo de variable automáticamente se convierte la otra variable
a String, de tal modo que es perfectamente correcto:
String saludo = “hola”;
int
n = 5;
www.javarevolutions.com
Canal YouTube: Java Revolutions
saludo = saludo + “ “ + n;// saludo toma el valor “hola 5”
4.2 Subcadenas
En la clase String hay un método que permite la extracción de una subcadena de caracteres de
otra. Su sintaxis es:
Nombre_String.substring((int)posición_inicial,(int)posición_final
);
Donde posición_inicial y posición_final son respectivamente la posición del primer carácter que
se desea extraer y del primer carácter que ya no se desea extraer.
String saludo = “hola”;
String subsaludo = “”;
Subsaludo = saludo.substring(0,2);// subsaludo toma el
valor “ho”
Puede extraerse un char de una cadena, para ello se emplea el método charAt(posición),
siendo posición la posición del carácter que se desea extraer.
4.3 Comparación de cadenas
Se empleo otro método de String: equals. Su sintaxis es:
cadena1.equals(cadena2);
Devuelve true si son iguales y false si son distintos.
El siguiente ejemplo permitirá ilustrar estas operaciones con Strings:
www.javarevolutions.com
Canal YouTube: Java Revolutions
public class Ejemplo5 {
public static void main(String[] args) {
String saludo = "Hola";
String saludo2 ="hola";
int n = 5;
//Imprime por consola la subcadena formada por los caracteres
//comprendidos entre el caractero 0 de saludo y hasta el
//carácter 2, sin incluir el último
prt(saludo.substring(0,2));
//Concatena saludo con un espacio en blanco y con el valor de
//la variable n
prt(saludo +" " + n);
//Imprime el resultado del test de igualdad entre saludo y
//saludo2. Son distintos, en Java se distingue entre
//mayúsculas y minúsculas.
prt("saludo == saludo2 "+ saludo.equals(saludo2));
}
static void prt(String s) {
System.out.println(s);
}
}
5 DEFINICIÓN DE VARIABLES
Al igual que C, Java requiere que se declaren los tipos de todas las variables empleadas. La
sintaxis de iniciación es la misma que C:
int i;
Sin embargo, y a diferencia que en C, se requiere inicializar todas las variables antes de usarlas, si
no el compilador genera un error y aborta la compilación. Se puede inicializar y asignar valor a
una variable en una misma línea:
www.javarevolutions.com
Canal YouTube: Java Revolutions
int i = 0;
Asignación e inicialización pueden hacerse en líneas diferentes:
int i ;
i = 0;
Es posible iniciar varias variables en una línea:
int i, j,k;
Después de cada línea de código, bien sea de iniciación o de código, al igual que en C va un ;.
En Java, al igual que en todo lenguaje de programación hay una serie de palabras reservadas que
no pueden ser empleadas como nombres de variables (if, int, char, else, goto....); alguna de estas
se emplean en la sintaxis del lenguaje, otras, como goto no se emplean en la actualidad pero se
han reservado por motivos de compatibilidad por si se emplean en el futuro.
Los caracteres aceptados en el nombre de una variable son los comprendidos entre “A-Z”, “a-z”,
_, $ y cualquier carácter que sea una letra en algún idioma.
6 OPERADORES
Los operadores básicos de Java son + , - , * , / para suma, resta, producto y división. El operador
/ representa la división de enteros si ambos operandos son enteros. Su módulo puede obtenerse
mediante el operador % (7/4= 1; 7% 4=3).
Además existen los operadores decremento e incremento: -- y ++ respectivamente. La operación
que realizan son incrementar y decrementar en una unidad a la variable a la que se aplican. Su
acción es distinta según se apliquen antes (++a) o después (a++) de la variable. El siguiente
programa ilustra estos distintos efectos:
public class Ejemplo2{
public static void main(String[] args) {
int i = 1;
www.javarevolutions.com
Canal YouTube: Java Revolutions
prt("i : " + i);
prt("++i : " + ++i); // Pre-incremento, primero
//incrementa y luego imprime por consola
prt("i++ : " + i++); // Post-incremento, primero imprime
//“2” por consola y luego incrementa i.
prt("i : " + i);//i por lo tanto vale 3
prt("--i : " + --i); // Pre-decremento, primero
//decrementa i y luego lo imprime por consola
prt("i-- : " + i--); // Post-decremento, primero imprime
//i por consola y luego de decrementa.
prt("i : " + i);//Ahora i vale 1
}
//esto nos ahorrara teclear. Invocando a prt podremos
//imprimir por consola la cadena de caracteres que le pasemos
static void prt(String s) {
System.out.println(s);
}
}
6.1 Exponenciación
En Java a diferencia que en otros lenguajes no existe el operador exponenciación. Tampoco
existen los operadores Seno o Coseno. Si se desea realizar una operación de exponenciación se
deberá invocar el método correspondiente de la clase Math de Java.lang. Estos métodos son
estáticos, por lo que no es necesario crear un objeto de dicha clase. Su sintaxis general es:
Math.metodo(argumentos);
En el siguiente código aparecen ejemplos. Si alguna vez deseamos realizar algún otro tipo de
operación y queremos ver si la soporta Java podemos hacerlo consultando la ayuda on-line de la
clase Math, o bien la documentación que podemos descargar los desde la misma página que él
jdk.
www.javarevolutions.com
Canal YouTube: Java Revolutions
public class Ejemplo3 {
public static void main(String[] args) {
int i = 45,j=2;
//Imprime por consola la cadena de caracteres “Cos i : “
//concatenado con el resultado de calcular el coseno de i
prt("Cos i : " + Math.cos(i));
prt("Sen i : " + Math.sin(i));
prt("j^i : " + Math.pow(j,i));
}
}
6.2 Operadores lógicos
En la tabla a continuación recogemos los operadores lógicos disponibles en Java:
Tabla 3: operadores lógicos
Operador
Operación que realiza
!
Not lógico
==
Test de igualdad
!=
Test de desigualdad
<
Menor que
>
Mayor que
<=
Menor o igual que
>=
Mayor o igual que
&&
And lógico
||
Or lógico
www.javarevolutions.com
Canal YouTube: Java Revolutions
Con el siguiente ejemplo se muestra la función de estos operadores:
import java.util.*;
public class Ejemplo4 {
public static void main(String[] args) {
//Creamos un objeto de tipo Random, almecenado un puntero a
//el en la variable rand. En el tema 5 se detallará como se
//crean objetos.
Random rand = new Random();
//el método nextInt() del objeto Random creado (se invoca
//como rand.nextInt()) genera un número aleatorio entero. En
//el tema 5 se explica que son los métodos y como emplearlos.
//El módulo 100 de un entero aleatorio será un entero
//aleatorio entre 0 y 100.
int i = rand.nextInt() % 100;
int j = rand.nextInt() % 100;
//Imprime I y j por consola
prt("i = " + i);
prt("j = " + j);
//Imprime diversas operaciones binarias sobre i y j, junto
//con su resultado.
prt("i > j es " + (i > j));
prt("i < j es " + (i < j));
prt("i >= j es " + (i >= j));
prt("i <= j es " + (i <= j));
prt("i == j es " + (i == j));
prt("i != j es " + (i != j));
prt("(i < 10) && (j < 10) es "
+ ((i < 10) && (j < 10)) );
prt("(i < 10) || (j < 10) es "
+ ((i < 10) || (j < 10)) );
www.javarevolutions.com
Canal YouTube: Java Revolutions
}
static void prt(String s) {
System.out.println(s);
}
}
Una posible salida de este programa es:
i = 85
j = 4
i > j es true
i < j es false
i >= j es true
i <= j es false
i == j es false
i != j es true
//true && false = false
(i < 10) && (j < 10) es false
//true || false = true
(i < 10) || (j < 10) es true
7. ESTRUCTURA DE CLASES
Vamos a comenzar analizando la clase Contador, para ir viendo las partes que forman una clase
una por una y en detalle. Este capítulo va a ser un poco aburrido por lo exhaustivo (aunque
algunos puntos más complicados como las excepciones y los threads los dejaremos para
después), pero me parece bueno tener un resumen completo de la sintaxis desde ahora.
Luego iremos armando pequeñas aplicaciones para probar cada cosa.
Recordemos la definición de la clase Contador:
// Implementación de un contador sencillo
public class Contador {
// Atributos
int cnt;
// Constructor
public Contador() {
www.javarevolutions.com
Canal YouTube: Java Revolutions
cnt = 0;
}
// Métodos
public int incCuenta() {
cnt++;
return cnt;
}
public int getCuenta() {
return cnt;
}
}
7.1 Declaración de la clase
La clase se declara mediante la línea public class Contador. En el caso más general, la declaración
de una clase puede contener los siguientes elementos:
[public] [final | abstract] class Clase [extends ClaseMadre]
[implements Interfase1 [, Interfase2 ]…]
o bien, para interfaces:
[public] interface Interfase [extends InterfaseMadre1 [,
InterfaseMadre2 ]…]
Como se ve, lo único obligatorio es class y el nombre de la clase. Las interfases son un caso de
clase particular que veremos más adelante.
7.2 El cuerpo de la clase
El cuerpo de la clase, encerrado entre { y }, es la lista de atributos (variables) y métodos
(funciones) que constituyen la clase.
No es obligatorio, pero en general se listan primero los atributos y luego los métodos.
7.3 Declaración de atributos
En Java no hay variables globales; todas las variables se declaran dentro del cuerpo de la clase o
dentro de un método. Las variables declaradas dentro de un método son locales al método; las
www.javarevolutions.com
Canal YouTube: Java Revolutions
variables declaradas en el cuerpo de la clase se dice que son miembros de la clase y son
accesibles por todos los métodos de la clase.
Por otra parte, además de los atributos de la propia clase se puede acceder a todos los atributos
de la clase de la que desciende; por ejemplo, cualquier clase que descienda de la clase Polygon
hereda los atributos npoints, xpoints e ypoints.
Finalmente, los atributos miembros de la clase pueden ser atributos de clase o atributos de
instancia; se dice que son atributos de clase si se usa la palabra clave static: en ese caso la
variable es única para todas las instancias (objetos) de la clase (ocupa un único lugar en
memoria). Si no se usa static, el sistema crea un lugar nuevo para esa variable con cada instancia
(o sea que es independiente para cada objeto).
La declaración sigue siempre el mismo esquema:
[private|protected|public] [static] [final] [transient]
[volatile] Tipo NombreVariable [= Valor];
7.4 Tipos de Definiciones de clases
Definir una clase como pública (public) significa que puede ser usada por cualquier clase en
cualquier paquete. Si no lo es, solamente puede ser utilizada por clases del mismo paquete (más
sobre paquetes luego; básicamente, se trata de un grupo de clases e interfaces relacionadas,
como los paquetes de biblioteca incluídos con Java).
Una clase final (final) es aquella que no puede tener clases que la hereden. Esto se utiliza
básicamente por razones de seguridad (para que una clase no pueda ser reemplazada por otra
que la herede), o por diseño de la aplicación.
Una clase abstracta (abstract) es una clase que puede tener herederas, pero no puede ser
instanciada. Es, literalmente, abstracta (como la clase Number definida en java.lang). ¿Para qué
sirve? Para modelar conceptos. Por ejemplo, la clase Number es una clase abstracta que
representa cualquier tipo de números (y sus métodos no están implementados: son abstractos);
las clases descendientes de ésta, como Integer o Float, sí implementan los métodos de la madre
Number, y se pueden instanciar.
www.javarevolutions.com
Canal YouTube: Java Revolutions
Por lo dicho, una clase no puede ser final y abstract a la vez (ya que la clase
abstract requiere descendientes…)
¿Un poco complejo? Se va a entender mejor cuando veamos casos particulares, como las
interfases (que por definición son abstractas ya que no implementan sus métodos).
7.5 Private, protected o public
Java tiene 4 tipos de acceso diferente a las variables o métodos de una clase: privado, protegido,
público o por paquete (si no se especifica nada).
De acuerdo a la forma en que se especifica un atributo, objetos de otras clases tienen distintas
posibilidades de accederlos:
Acceso desde:
private
protected
public
package
la propia clase
S
S
S
S
subclase en el mismo paquete
N
S
S
S
otras clases en el mismo paquete
N
S
S
S
subclases en otros paquetes
N
X
S
N
otras clases en otros paquetes
N
N
S
N
S: puede acceder
N: no puede acceder
X: puede acceder al atributo en objetos que pertenezcan a la subclase, pero no en los que
pertenecen a la clase madre. Es un caso especial ; más adelante veremos ejemplos de todo esto.
8 ESTRUCTURA DE LOS MÉTODOS
Los métodos, como las clases, tienen una declaración y un cuerpo.
www.javarevolutions.com
Canal YouTube: Java Revolutions
La declaración es del tipo:
[private|protected|public] [static] [abstract] [final] [native]
[synchronized] TipoDevuelto NombreMétodo ( [tipo1 nombre1[, tipo2
nombre2 ]…] ) [throws excepción1 [,excepción2]… ]
A no preocuparse: poco a poco aclararemos todo con ejemplos.
Básicamente, los métodos son como las funciones de C: implementan, a través de funciones,
operaciones y estructuras de control, el cálculo de algún parámetro que es el que devuelven al
objeto que los llama. Sólo pueden devolver un valor (del tipo TipoDevuelto), aunque pueden no
devolver ninguno (en ese caso TipoDevuelto es void). Como ya veremos, el valor de retorno se
especifica con la instrucción return, dentro del método.
Los métodos pueden utilizar valores que les pasa el objeto que los llama (parámetros), indicados
con tipo1 nombre1, tipo2 nombre2… en el esquema de la declaración.
Estos parámetros pueden ser de cualquiera de los tipos ya vistos. Si son tipos básicos, el método
recibe el valor del parámetro; si son arrays, clases o interfases, recibe un puntero a los datos
(referencia). Veamos un pequeño ejemplo:
public int AumentarCuenta(int cantidad) {
cnt = cnt + cantidad;
return cnt;
}
Este método, si lo agregamos a la clase Contador, le suma cantidad al acumulador cnt. En
detalle:

el método recibe un valor entero (cantidad)

lo suma a la variable de instancia cnt

devuelve la suma (return cnt)
¿Cómo hago si quiero devolver más de un valor? Por ejemplo, supongamos que queremos hacer
un método dentro de una clase que devuelva la posición del mouse.
Lo siguiente no sirve:
www.javarevolutions.com
Canal YouTube: Java Revolutions
void GetMousePos(int x, int y) {
x = ….;
// esto no sirve!
y = ….;
// esto tampoco!
}
porque el método no puede modificar los parámetros x e y (que han sido pasados por valor, o
sea que el método recibe el valor numérico pero no sabe adónde están las variables en
memoria).
La solución es utilizar, en lugar de tipos básicos, una clase:
class MousePos { public int x, y; }
y luego utilizar esa clase en nuestro método:
void GetMousePos( MousePos m ) {
m.x = ……;
m.y = ……;
}
8.1 El resto de la declaración
Public, private y protected actúan exactamente igual para los métodos que para los atributos,
así que veamos el resto.
Los métodos estáticos (static), son, como los atributos, métodos de clase; si el método no es
static es un método de instancia. El significado es el mismo que para los atributos: un método
static es compartido por todas las instancias de la clase.
Ya hemos hablado de las clases abstractas; los métodos abstractos (abstract) son aquellos de los
que se da la declaración pero no la implementación (o sea que consiste sólo del
encabezamiento). Cualquier clase que contenga al menos un método abstracto (o cuya clase
madre contenga al menos un método abstracto que no esté implementado en la hija) es una
clase abstracta.
Es final un método que no puede ser redefinido por ningún descendiente de la clase.
www.javarevolutions.com
Canal YouTube: Java Revolutions
Las clases native son aquellas que se implementan en otro lenguaje (por ejemplo C o C++) propio
de la máquina. Sun aconseja utilizarlas bajo riesgo propio, ya que en realidad son ajenas al
lenguaje. Pero la posibilidad de usar viejas bibliotecas que uno armó y no tiene ganas de
reescribir existe!.
Las clases synchronized permiten sincronizar varios threads para el caso en que dos o más
accedan concurrentemente a los mismos datos. De nuevo, más detalles habrá en el futuro,
cuando hablemos de threads.
Finalmente, la cláusula throws sirve para indicar que la clase genera determinadas excepciones.
También hablaremos de las excepciones más adelante.
En la próxima veremos el cuerpo de la declaración y empezaremos a armar algunos ejemplos
concretos para ir aclarando todos estos conceptos…
8.2 El cuerpo de los métodos
Otra vez recordaremos nuestra vieja clase Contador:
// Implementación de un contador sencillo
public class Contador {
public int incCuenta() {
cnt++;
return cnt;
}
}
Dentro de los métodos pueden incluirse:

Declaración de variables locales

Asignaciones a variables

Operaciones matemáticas

Llamados a otros métodos:
 dentro de la clase
www.javarevolutions.com
Canal YouTube: Java Revolutions
 de instancia, de otras clases
 de clase, de cualquier clase

Estructuras de control

Excepciones (try, catch, que veremos más adelante)
8.3 Declaración de variables locales
Las variables locales se declaran igual que los atributos de la clase:
Tipo NombreVariable [= Valor];
Ej: int suma;
float precio;
Contador laCuenta;
Sólo que aquí no se declaran private, public, etc., sino que las variables definidas dentro del
método sólo son accesibles por él.
Las variables pueden inicializarse al crearse:
Ej: int suma = 0;
float precio = 12.3;
Contador laCuenta = new Contador ( );
8.4 Asignaciones a variables
Se asigna un valor a una variable mediante el signo =:
www.javarevolutions.com
Canal YouTube: Java Revolutions
Variable = Constante | Expresión ;
Ej: suma = suma + 1;
precio = 1.05 * precio;
laCuenta.cnt = 0;
El último caso es válido si cnt es una variable pública de la clase Contador. Personalmente no
creo conveniente acceder directamente a variables de otro objeto, ya que futuras
modificaciones del objeto llamado o del que llama puede propender la difusión de errores… Es
mejor usar métodos como getCuenta o un hipotético inicializarContador para ello. De hecho,
algunos sugieren que todas las variables de una clase se declaren como private.
En el primer caso, o sea en general:
Variable = Variable Operador Expresión;
se puede escribir en forma más sencilla:
Variable Operador= Expresión;
Por ejemplo, suma = suma + 9 - cantidad;
puede escribirse: suma += 9-cantidad;
y precio = precio * 0.97;
como: precio *= 0.97;
8.5 Llamadas a métodos
Se llama a un método de la misma clase simplemente con el nombre del método y los
parámetros entre paréntesis, como se ve, entre otros, en el ejemplo en negrita:
// Archivo:
Complejo.java
// Compilar con:
javac Complejo.java
public final class Complejo extends Number {
www.javarevolutions.com
Canal YouTube: Java Revolutions
// atributos:
private float x;
private float y;
// constructor:
public Complejo(float
rx, float iy) {
x = rx;
y = iy;
}
// métodos:
public float Norma() {
return (float)Math.sqrt(x*x+y*y);
}
// obligatorios (son abstractos en Number):
public double doubleValue() {
return (double)Norma( );
}
public float floatValue() {
return Norma();
}
public int intValue() {
return (int)Norma();
}
public long longValue() {
return (long)Norma();
}
public String toString() {
return "("+x+")+i("+y+")";
}
}
Pueden probar la clase (mínima) con el siguiente ejemplo de aplicación; la línea en negrita es un
ejemplo de un llamado a un método de un objeto de otra clase. Notar que es este caso, es
necesario llamar al método sobre un objeto (instancia) existente, por lo que se indica:
www.javarevolutions.com
Canal YouTube: Java Revolutions
Nombre_del_Objeto<punto>Nombre_del_Método(parámetros)
// Archivo: Ejemplo4.java
// Compilar con: javac Ejemplo4.java // Ejecutar con: java
Ejemplo4 import java.io.*;
public class Ejemplo4 {
public static void main(String args[]) {
Complejo numComp = new Complejo(4,-3);
System.out.println(numComp.toString());
System.out.println(numComp.Norma());
}
}
En la clase Complejo tenemos también un ejemplo de un llamado a un método de clase, o sea
static:
return (float)Math.sqrt(x*x+y*y);
Como el método es de clase, no hace falta llamarlo para un objeto en particular. En ese caso, en
lugar del nombre de un objeto existente se puede utilizar directamente el nombre de la clase:
Nombre_de_la_Clase<punto>Nombre_del_Método(parámetros)
En el próximo capítulo veremos las estructuras de control y empezaremos a armar ejemplos para
repasar todo esto.
9 ESTRUCTURAS DE CONTROL
SENTENCIAS CONDICIONALES
Ejecutan un código u otro en función de que se cumplan o no una determinada condición.
Pasemos a ver sus principales tipos.
9.1 if…[else]
www.javarevolutions.com
Canal YouTube: Java Revolutions
La más común de todas, permite ejecutar una instrucción (o secuencia de instrucciones) si se da
una condición dada (o, mediante la cláusula else, ejecutar otra secuencia en caso contrario).
if (expresión_booleana) instrucción_si_true;
[else instrucción_si_false;]
o bien:
if (expresión_booleana) {
instrucciones_si_true;
}
else {
instrucciones_si_false;
}
Por ejemplo:
public final String toString() {
if (y<0)
return x+"-i"+(-y);
else
return +x+"+i"+y;
}
9.2 Switch…case…brake…default
Permite ejecutar una serie de operaciones para el caso de que una variable tenga un valor
entero dado. La ejecución saltea todos los case hasta que encuentra uno con el valor de la
variable, y ejecuta desde allí hasta el final del case o hasta que encuentre un break, en cuyo caso
salta al final del case. El default permite poner una serie de instrucciones que se ejecutan en
caso de que la igualdad no se de para ninguno de los case.
switch (expresión_entera) {
case (valor1): instrucciones_1;
www.javarevolutions.com
Canal YouTube: Java Revolutions
[break;]
case (valor2): instrucciones_2;
[break;]
…..
case (valorN): instrucciones_N;
[break;]
default: instrucciones_por_defecto;
}
Por ejemplo:
switch (mes) {
case (2):
if (bisiesto()) dias=29;
else dias=31;
break;
case (4):
case (6):
case (9):
case (11):
dias = 30;
break;
default:
dias = 31;
}
BUCLES
Son instrucciones que nos permiten repetir un bloque de código mientras se cumpla una
determinada condición. Pasemos a ver sus tipos.
9.3 While
Permite ejecutar un grupo de instrucciones mientras se cumpla una condición dada:
www.javarevolutions.com
Canal YouTube: Java Revolutions
while (expresión_booleana) {
instrucciones…
}
Por ejemplo:
while ( linea != null) {
linea = archivo.LeerLinea();
System.out.println(linea);
}
9.4 Do…while
Similar al anterior, sólo que la condición se evalúa al final del ciclo y no al principio:
do {
instrucciones…
} while (expresión_booleana);
Por ejemplo:
do {
linea = archivo.LeerLinea();
if (linea != null) System.out.println(linea);
} while (linea != null);
9.5 For
También para ejecutar en forma repetida una serie de instrucciones; es un poco más complejo:
for ( instrucciones_iniciales; condición_booleana;
instruccion_repetitiva_x ) {
instrucciones…
www.javarevolutions.com
Canal YouTube: Java Revolutions
}
Si bien las instrucciones pueden ser cualquiera (el bucle se repite mientras la condición sea
verdadera), lo usual es utilizarlo para "contar" la cantidad de veces que se repiten las
instrucciones; se podría indicar así:
for ( contador = valor_inicial; contador < valor_final; contador+
+ ) {
instrucciones…
}
Por ejemplo:
for ( i=0; i<10; i++ ) {
System.out.println( i );
}
o, para contar hacia atrás:
for ( i=10; I>0; I-- ) {
System.out.println( i );
}
9.6 Break y continue
Estas instrucciones permiten saltar al final de una ejecución repetitiva (break) o al principio de
la misma (continue).
Por ejemplo, en:
www.javarevolutions.com
Canal YouTube: Java Revolutions
import java.io.*;
class Bucles {
public static void main (String argv[ ]) {
int i=0;
for (i=1; i<5; i++) {
System.out.println("antes "+i);
if (i==2) continue;
if (i==3) break;
System.out.println("después "+i);
}
}
}
La salida es:
antes 1
después 1
antes 2
antes 3
Por qué? "i" comienza en 1 (imprime "antes" y "después"); cuando pasa a 2, el continue salta
al principio del bucle (no imprime el "después"). Finalmente, cuando "i" vale 3, el break da por
terminado el bucle for.
10 CLASES Y HERENCIA
Herencia
Cuando en Java indicamos que una clase “extends” otra clase estamos indicando que es una
clase hija de esta y que, por lo tanto, hereda todos sus métodos y variables. Este es un poderoso
mecanismo para la reusabilidad del código. Podemos heredar de una clase, por lo cual partimos
de su estructura de variables y métodos, y luego añadir lo que necesitemos o modificar lo que no
se adapte a nuestros requerimientos. Veamos un ejemplo:
www.javarevolutions.com
Canal YouTube: Java Revolutions
class Animal{
protected int edad;
String nombre;
public Animal(){
}
public Animal(int _edad, String _nombre){
edad = _edad;
nombre = _nombre;
}
public void nace(){
System.out.println("Hola mundo");
}
public void getNombre(){
System.out.println(nombre);
}
public void getNombre(int i){
System.out.println(nombre +" " +edad);
}
public void getEdad(){
System.out.println(edad);
}
}
//La clase Perro extiende a Animal, heredando sus métodos y
//variables
public class Perro extends Animal{
Perro(){
edad = 0;
nombre ="Tobi";
}
Perro(int edad, String nombre){
//Esta sentencia invoca a un constructor de la clase padre.
super(edad,nombre);
}
www.javarevolutions.com
Canal YouTube: Java Revolutions
//Método estático que recibe un objeto de tipo Perro e
//invoca a su método getEdad()
static void get1(Perro dog){
//El métod getEdad() no está definido en Perro, lo ha
//heredado de Animal.
dog.getEdad();
}
public static void main (String[] args){
//Creamos un objeto de tipo Perro
Perro dog = new
Perro(8,"Bambi");
//Invocamos al método estátioco get1 pasándole el objeto //
de tipo Perro creado.
Perro.get1(dog);
}
}
public class Perro2 extends Animal{
Perro2(){
edad = 0;
nombre ="Tobi";
}
Perro2(int edad, String nombre){
super(edad,nombre);
}
static void get1(Perro2 dog){
dog.getEdad();
//Cuando ejecutemos este método en vez de ejecutarse el
//código de la clase padre se ejecutará el código de la clase
//hija, ya que ésta ha sobreescrito este método.
dog.getNombre(11);
}
//Sobreescribe al método de la clase padre.
getNombre(int i){
System.out.println(nombre +" " +i);
}
public static void main (String[] args){
Perro2 dog = new Perro2(8,"hola");
Perro2.get1(dog);
}
}
www.javarevolutions.com
Canal YouTube: Java Revolutions
public void
10.1 Creación y referencia a objetos
Aunque ya hemos visto como se crea un objeto vamos a formalizarlo un poco. Un objeto en el
ordenador es esencialmente un bloque de memoria con espacio para guardar las variables de
dicho objeto. Crear el objeto es sinónimo de reservar espacio para sus variables, inicializarlo es
darle un valor a estas variables. Para crear un objeto se utiliza el comando new. Veámoslo sobre
un ejemplo:
class Fecha{
int dia,mes,ano;
Fecha(){
dia=1;
mes = 1;
ano = 1900;
}
Fecha (int _dia, int _mes, int _ano){
dia= _dia;
mes = _mes;
ano = _ano;
}
} ///:~
Fecha hoy;
hoy = new Fecha();
Con el primer comando hemos creado un puntero que apunta a una variable tipo fecha, como
está sin inicializar apuntara a null. Con el segundo inicializamos el objeto al que apunta hoy,
reservando espacio para sus variables. El constructor las inicializará, tomando el objeto hoy el
valor 1-1-1900.
Fecha un_dia = new Fecha(8,12,1999);
Con esta sentencia creamos una variable que se llama un_dia con valor 8-12-1999.
Una vez creado un objeto será posible acceder a todas sus variables y métodos públicos, así por
ejemplo en el ejemplo anterior un_dia.dia = 8. Si la variable fuese privada solo podrían acceder a
ella sus instancias:
www.javarevolutions.com
Canal YouTube: Java Revolutions
class Fecha{
private int dia,mes,ano;
Fecha(){
dia=1;
mes = 1;
ano = 1900;
}
Fecha (int ndia, nmes, nano){
dia= ndia;
mes = nmes;
ano = nano;
}
}
De este modo no podríamos acceder a las variables de la clase fecha, para acceder a ella
tendríamos que hacerlo mediante métodos que nos devolviesen su valor. A esto se le denomina
encapsulación. Esta es la forma correcta de programar OOP: no debemos dejar acceder a las
variables de los objetos por otro procedimiento que no sea paso de mensajes entre métodos.
10.2 this
Es una variable especial de sólo lectura que proporciona Java. Contiene una referencia al objeto
en el que se usa dicha variable. A veces es útil que un objeto pueda referenciarse a si mismo:
class Cliente{
public Cliente(String n){
//Llamamos al otro constructor. El empleo de this ha de ser
//siempre en la primera línea dentro del constructor.
this(n, Cuenta.nuevo_numero());
.....
}
public Cliente (String n, int a){
nombre = n;
numero_cuenta = a;
}
.....
}
Otro posible uso de this, que ya se ha visto en ejemplos anteriores es diferenciar entre variables
www.javarevolutions.com
Canal YouTube: Java Revolutions
locales de un método o constructor y variables del objeto. En los códigos del cd
correspondientes a los ejemplos Perro.java y Perro2.java el constructor de la clases Animal
aunque realiza la misma función que los que se recogen en estos apuntos son ligeramente
diferentes:
public Animal(int edad, String nombre){
//this.edad = varaible del objeto Perro
//edad = variable definida sólo dentro del constructor
this.edad =edad;
this.nombre=nombre;
}
10.3 super
Del mismo modo que this apunta al objeto actual tenemos otra variable super que apunta a la
clase de la cual se deriva nuestra clase
class Gato {
void hablar(){
System.out.println("Miau");
}
}///~
class GatoMagico extends Gato {
boolean gentePresente;
void hablar(){
if(gentePresente)
//Invoca al método sobreescrito de la clase padre
super.hablar();
else
System.out.println("Hola");
}
}
Uno de los principales usos de super es, como ya se empleó en un ejemplo, llamar al constructor
de la clase padre.
www.javarevolutions.com
Canal YouTube: Java Revolutions
10.4 Interfaces
En Java no está soportada la herencia múltiple, esto es, no está permitido que una misma clase
pueda heredar las propiedades de varias clases padres. En principio esto pudiera parecer una
propiedad interesante que le daría una mayor potencia al lenguaje de programación, sin
embargo los creadores de Java decidieron no implementar la herencia múltiple por considerar
que esta añade al código una gran complejidad (lo que hace que muchas veces los
programadores que emplean programas que sí la soportan no lleguen a usarla).
Sin embargo para no privar a Java de la potencia de la herencia múltiple sus creadores
introdujeron un nuevo concepto: el de interface. Una interface es formalmente como una clase,
con dos diferencias: sus métodos están vacíos, no hacen nada, y a la hora de definirla en vez de
emplear la palabra clave “class” se emplea “inteface”. Veámoslo con un ejemplo:
interface Animal{
public int edad = 10;
public String nombre = "Bob";
public void nace();
public void getNombre();
void getNombre(int i);
} ///:~
Cabe preguntarnos cual es el uso de una interface si sus métodos están vacíos. Bien, cuando una
clase implementa una interface lo que estamos haciendo es una promesa de que esa clase va a
implementar todos los métodos de la interface en cuestión. Si la clase que implementa la
interface no “sobrescribiera” alguno de los métodos de la interface automáticamente esta clase
se convertiría en abstracta y no podríamos crear ningún objeto de ella. Para que un método
sobrescriba a otro ha de tener el mismo nombre, se le han de pasar los mismos datos, ha de
devolver el mismo tipo de dato y ha de tener el mismo modificador que el método al que
sobrescribe. Si no tuviera el mismo modificador el compilador nos daría un error y no nos dejaría
seguir adelante. Veámoslo con un ejemplo de una clase que implementa la anterior interface:
www.javarevolutions.com
Canal YouTube: Java Revolutions
interface Animal{
public int edad = 10;
public String nombre = "Bob";
public void nace();
public void getNombre();
void getNombre(int i);
} ///:~
public class Perro3 implements Animal{
Perro3(){
getNombre();
getNombre(8);
}
//Compruévese como si cambiamos el nombre del método a nac()
//no compila ya que no henos sobreescrito todos los métodos
//de la interfaz.
public void nace(){
System.out.println("hola mundo");
}
public void getNombre(){
System.out.println(nombre );
}
public void getNombre(int i){
System.out.println(nombre +" " +i);
}
public static void main (String[] args){
Perro3 dog = new Perro3();
//Compruevese como esta línea da un error al compilar debido
//a intentar asignar un valor a una variable final
// dog.edad = 8;
}
} ///:~
Las variables que se definen en una interface llevan todas ellas el atributo final, y es obligatorio
darles un valor dentro del cuerpo de la interface. Además no pueden llevar modificadores
private ni protected, sólo public. Su función es la de ser una especie de constantes para todos los
www.javarevolutions.com
Canal YouTube: Java Revolutions
objetos que implementen dicha interface.
Por último decir que aunque una clase sólo puede heredar propiedades de otra clase puede
implementar cuantas interfaces se desee, recuperándose así en buena parte la potencia de la
herencia múltiple.
interface Animal1{
public int edad = 10;
public String nombre = "Bob";
public void nace();
}
interface Animal2{
public void getNombre();
}
interface Animal3{
void getNombre(int i);
}
public class Perro4 implements Animal1,Animal2,Animal3{
Perro4(){
getNombre();
getNombre(8);
//edad = 10; no podemos cambiar este valor
}
public void nace(){
System.out.println("hola mundo");
}
public void getNombre(){
System.out.println(nombre );
}
public void getNombre(int i){
System.out.println(nombre +" " +i);
}
public static void main (String[] args){
Perro4 dog = new Perro4();
}
}
www.javarevolutions.com
Canal YouTube: Java Revolutions
Descargar