Indice Introducción a Java (I). Indice Índice Tipos de datos y operadores Entradas y Salidas...

74
Indice Introducción a Java (I)

Transcript of Indice Introducción a Java (I). Indice Índice Tipos de datos y operadores Entradas y Salidas...

Page 1: Indice Introducción a Java (I). Indice Índice Tipos de datos y operadores Entradas y Salidas básicas Sentencias de control Clases 2.

Indice

Introducción a Java (I)

Page 2: Indice Introducción a Java (I). Indice Índice Tipos de datos y operadores Entradas y Salidas básicas Sentencias de control Clases 2.

Indice

Índice

• Tipos de datos y operadores• Entradas y Salidas básicas• Sentencias de control• Clases

2

Page 3: Indice Introducción a Java (I). Indice Índice Tipos de datos y operadores Entradas y Salidas básicas Sentencias de control Clases 2.

Indice

Tipos de datos y operadores

Page 4: Indice Introducción a Java (I). Indice Índice Tipos de datos y operadores Entradas y Salidas básicas Sentencias de control Clases 2.

Indice

Variables• Una variable no es algo muy diferente de lo que hemos aprendido en matemáticas.

Pensemos en las siguientes operaciones:– El largo de la parcela es 60 metros– El ancho de la parcela es 70 metros– El área es el producto del ancho por el largo: 4200

• ¿Por qué son necesarias las variables?– Porque necesitamos etiquetas o identificadores para cosas tales como ancho, largo, etc.– Porque necesitamos almacenar datos asociados a dichos identificadores (60, 70, 4200)

• Un ejemplo en Java:public static void main(String[] args) {

System.out.println( "Ha entrado en la aplicación");float largo;float ancho;float area;largo = 60;ancho = 70;area = ancho * largo; // ¿ Cómo visualizar el área de la parcela

}

4

Page 5: Indice Introducción a Java (I). Indice Índice Tipos de datos y operadores Entradas y Salidas básicas Sentencias de control Clases 2.

Indice

Variables: las reglas básicas• Regla básica: toda variable debe ser declarada antes de ser utilizada• En el formato de la declaración hay que tener en cuenta:

– Lo básico, especificar:• El tipo de dato• El nombre o identificador de la variable

– Lo opcional es:• Dar valor a la variable por primera vez (inicializar)• Declarar otras variables en la misma línea (ojo: del mismo tipo)

• Formato:Tipo nombre [ = valor ] [, nombre [ = valor ] ... ];

• Ejemplos:int alto, ancho = 0, edad;char x = ‘s’, b;

• El programador tiene completa libertad a la hora de dar nombre a una variable. Por ejemplo, no hay obligación de llamar a las variables enteras con nombres como “número”, “entero”, etc.

• Lo mejor a la hora de dar un nombre es dejarse llevar por el sentido común: claridad, es decir, tratar de ser “significativo” sin alargarse en exceso. Por ejemplo, el nombre “edad” es más significativo que usar simplemente “e”. La costumbre de dar nombres no significativos es uno de los vicios que conduce a crear código “solipsista”: sólo lo comprende el programador que lo creó (siempre que no haya pasado mucho tiempo, en cuyo caso lo normal es que no lo comprenda ni la persona que lo hizo)

5

Page 6: Indice Introducción a Java (I). Indice Índice Tipos de datos y operadores Entradas y Salidas básicas Sentencias de control Clases 2.

Indice

Los tipos de datos: enteros y coma flotante

• Del mismo modo que existen diferentes tipos de vehículos existen diferentes tipos de variables

• El tamaño en bits, a diferencia de C/C++, es fijo, es decir, no varía en función de la máquina. Esto facilita la portabilidad

• Enteros:– byte: 8 bits (-128 a 127)– short: 16 bits (-32.768 a 32.767)– int: 32 bits (-2.147.483.648 a 2.147.483.647)– long: 64 bits (+/- 9x1018)

• En coma flotante, también llamados reales. Se utilizan cuando se precisan posiciones decimales:– float: 32 bits (3.4e-038 a 3.4e+038)– double: 64 bits (1.7e-308 a 1.7e+308)

6

Page 7: Indice Introducción a Java (I). Indice Índice Tipos de datos y operadores Entradas y Salidas básicas Sentencias de control Clases 2.

Indice

Elegir un tipo de datos• En principio parece que lo más fácil sería trabajar con un único tipo de

dato. ¿Parece lógico tener diferentes tipos de datos?• La respuesta más sencilla es responder con una pregunta: ¿parece

sensato tener el mismo tipo de vehículo para transportar 5 personas, transportar 3 toneladas de carga o para llevar a 55 personas?

• Tenemos diferentes tipos de datos con la finalidad de optimizar. Del mismo modo que no es sensato usar el motor de un autobus para un turismo, no es sensato emplear 64 bits si queremos contar del 1 al 10

• Por tanto, parece que el primer criterio para elegir el tipo es la optimización: no malgastar memoria. Pero hay un criterio más importante, el sentido común, que nos indica que resulta prudente actuar con holgura. De hecho, en nuestra vida cotidiana no llevamos nuestros coches siempre llenos y perfectamente optimizados. Sino que con frecuencia, transportan menos personas que su límite máximo

7

Page 8: Indice Introducción a Java (I). Indice Índice Tipos de datos y operadores Entradas y Salidas básicas Sentencias de control Clases 2.

Indice

Un ejemplo con double• Un ejemplo para calcular el área de un círculo

(PI*r2)public class j01_radio { public static void main(String[] args) throws IOException { double PI = 3.1416; double radio = 3.2, area;

area = radio * radio * PI; // Calculo el áreaSystem.out.println( "El área es: " + area);

}}

• Ejercicio: hacer un programa que calcule volumen de un contenedor a partir de su largo, ancho y altura (pueden admitir dos decimales).

8

Page 9: Indice Introducción a Java (I). Indice Índice Tipos de datos y operadores Entradas y Salidas básicas Sentencias de control Clases 2.

Indice

Booleanos• Es un tipo de dato propio de una lógica binaria: sólo tiene como valores

true o false.int edad = 0; boolean mayor_de_edad = false;edad = 18;mayor_de_edad = true;

• Es el tipo utilizado para evaluar los condicionales:int edad = 0; boolean mayor_de_edad = false;if (edad >= 18) // Si es verdad que la edad es > ó = que 18

mayor_de_edad = true; // entonces es mayor de edadif (mayor_de_edad == true) // Si es verdad que es mayor de edad ...

System.out.println( “Puede obtener el carnet B1” );

• El último condicional se puede escribir de manara más cómoda (y más usual):

if (mayor_de_edad) // Si es verdad que es mayor de edad ...System.out.println( “Puede obtener el carnet B1” );

9

Page 10: Indice Introducción a Java (I). Indice Índice Tipos de datos y operadores Entradas y Salidas básicas Sentencias de control Clases 2.

Indice

Caracteres (char)• En Java los caracteres se almacenan en variables de 16 bits. Se utiliza un

formato estándar e internacional denominado Unicode que admite 65.537 caracteres, de esta forma podemos utilizar desde el latín hasta el arábigo. Unicode es el formato más utilizado en Internet.

• En el siguiente ejemplo cambiamos el valor de una variable char:char cuadricula = ‘A’;System.out.println( “La cuadrícula del mapa es ” + cuadricula );cuadricula = ‘b’;System.out.println( “La cuadrícula del mapa es ” + cuadricula );

• El siguiente ejemplo nos muestra como funciona internamente el ordenador: asocia a cada carácter un número. Puesto que con 16 bits podemos representar números enteros de 0 a 65.536, entonces podemos representar 65.537 caracteres. En nuestro ejemplo asociamos a un char el número 126, que se representa en formato de carácter como ‘~’:

char a = 126;System.out.println( “El carácter es ” + a );

• Observar que una cadenas de caracteres (String) se delimita por comillas dobles y los caracteres aislados (char) se delimitan por comillas simples.

10

Page 11: Indice Introducción a Java (I). Indice Índice Tipos de datos y operadores Entradas y Salidas básicas Sentencias de control Clases 2.

Indice

String• String no es un tipo simple (como float, char, etc.), sino una clase que nos ayuda a

manejar de forma sencilla cadenas de caracteres.• Ejemplos de instancias:

String j = “Hola mundo”;String k = new String( “Hola mundo” );

• Podemos concatenar cadenas:String k = "Hola“, String m = "Adios";String h = "Saludos: " + k + " y " + m;System.out.println( h );

• Podemos saber su ancho:String k = “Antonio”;System.out.println( k.length() );

• Mediante compareTo() podemos ordenar diferentes cadenas (ver más adelante)• Conversión de númerico a cadena mediante el método static valueOf():

int anio = 1999;String p = String.valueOf( anio);System.out.println( p );

• La conversión inversa se hace con métodos static que están en las clases Double, Float, etc:

radio = Double.parseDouble( cadena ); // Convierto el String en double

• Se puede acceder a un carácter de la cadena:char car = c.charAt(1);

11

Page 12: Indice Introducción a Java (I). Indice Índice Tipos de datos y operadores Entradas y Salidas básicas Sentencias de control Clases 2.

Indice

Ámbito de vida• El ámbito de una variable u objeto es el espacio del programa en el que

esa variable existe. Por ello, se habla de “ámbito de vida”

• De forma general (hay excepciones que veremos más adelante), la vida de una variable comienza con su declaración y termina en el bloque en el que fue declarada (los bloques de código se delimitan por llaves: {}). Por ejemplo, ¿cuál es el ámbito de la variable ‘radio’ y del vector ‘args’?:

public static void main(String[] args){ double PI = 3.1416; double radio = 3; System.out.println( “El área es” + (PI*radio*radio) );}

• Más adelante profundizaremos en los diferentes tipos de ámbito

12

Page 13: Indice Introducción a Java (I). Indice Índice Tipos de datos y operadores Entradas y Salidas básicas Sentencias de control Clases 2.

Indice

Conversión de tipos• Hemos visto que los datos tienen un tipo. Pero en ocasiones nos conviene

convertir un dato de su tipo original a otro• Tipos de conversión:

– Automática o implícita. El tipo destino es más grande (mayor número de bits) que el tipo origen (ensanchamiento o promoción):

int Origen = 65;float Destino = 4.35f;Destino = Origen; // ¿Cuál es el valor de ‘Destino’?

También hay conversión automática ante tipos compatibles. Por ejemplo, la asignación de un int a un char que vimos anteriormente

– Explicita. La conversión se produce cuando el tipo destino es más pequeño que el origen (estrechamiento). Para ello debemos realizar un moldeado (cast):

double Origen = 65.13;int Destino = 4;Destino = (int) Origen; // ¿Cuál es el valor de ‘Destino’?

– La conversión por medio de métodos es en realidad una aplicación de los tipos de conversión anteriores. Para ver ejemplos (transparencia dedicada a la clase String):

• String p = String.valueOf( anio);• double radio = Double.parseDouble( cadena );

13

Page 14: Indice Introducción a Java (I). Indice Índice Tipos de datos y operadores Entradas y Salidas básicas Sentencias de control Clases 2.

Indice

Comprender la conversión de tipos• Supongamos que tenemos en una variable (int) el precio de un producto. Queremos

incrementarlo en un 20%:int precio = 10000;precio = precio * 1.2;

• Este código parece correcto, sin embargo el compilador nos informa de un error: “Error num.: 355 : puede perderse precisión: double, hacía falta int”. ¿Cuál es la razón? Para entenderlo, conviene comprender como trabaja el ordenador:

– El ordenador trata de realizar el producto (precio*1.2) entre un int y un double (1.2), para lo cual el ordenador convierte de forma automática el int en un double. Hasta aquí todo va bien, el resultado de multiplicar dos números double es un double:

14

precio = precio * 1.2;

(int) (double)

(conversión automática a

double)

(double) El problema viene a continuación: no hay conversión automática de un double

(el resultado del producto) a un int (la variable a la izquierda del operador =) Para que se produzca esta conversión es necesario realizar un moldeado

(cast): precio = (int) (precio * 1.2); // Esto si es correcto

Page 15: Indice Introducción a Java (I). Indice Índice Tipos de datos y operadores Entradas y Salidas básicas Sentencias de control Clases 2.

Indice

Matrices (I)• Una matriz es un conjunto ordenado de variables u objetos, con las siguientes características:

– Tienen el mismo tipo– Tienen el mismo nombre (aunque hay casos poco usuales de matrices anónimas)– Si tienen el mismo nombre, ¿cómo se diferencia un elemento de otro? La respuesta es por el índice

• Formatos:– Con new: Tipo nombre[] = new tipo[tamaño]– Sin new: Tipo nombre[] = {x, y, ...}

• Un ejemplo:int m[] = new int[3];m[0] = 5;m[1] = 9;m[2] = 2;System.out.println( m[1] );

15

Valor:

Posición:

5 9 2

0 1 2

Matriz

Page 16: Indice Introducción a Java (I). Indice Índice Tipos de datos y operadores Entradas y Salidas básicas Sentencias de control Clases 2.

Indice

Matrices (II)• Un ejemplo en el que incremento en un 50% el tercer elemento de la

matriz:

public static void main(String[] args) { int depositos[]; int num_depositos = 4; depositos = new int[num_depositos]; // Igual que: int depositos[] = new int[4]; depositos[0] = depositos[1] = 300; depositos[2] = depositos[3] = 700; System.out.println( "Litros del segundo deposito:" + depositos[1]); depositos[2] = (int) (depositos[2] * 1.5); // Incremento de un 50% System.out.println( "Litros del tercer deposito:" + depositos[2]);}

• ¿Por qué necesito hacer casting?

16

Page 17: Indice Introducción a Java (I). Indice Índice Tipos de datos y operadores Entradas y Salidas básicas Sentencias de control Clases 2.

Indice

Matrices (III)• Es importante destacar una diferencia a la hora de crear una matriz:

– Si trabajamos con tipos simples (int, char, float, double, etc.) tenemos que usar el operador new una vez, al crear la matriz:

int botes[] = new botes[4];Botes[0] = 325;

– Si trabajamos con tipos compuestos (todos los demás, es decir, clases de Java como String, o cualquier otra creada por el programador), entonces hay que usar dos veces dicho operador: una al crear la matriz y luego tantas veces como objetos queramos almacenar en ella:

public static void main(String[] args) {Vehiculo mios[] = new Vehiculo[2];mios[0] = new vehiculo();mios[1] = new vehiculo();mios[0].definir_precio_bajo();mios[1].definir_precio_bajo();mios[1].mostrar();

}

17

Vehiculo.java:package xxx;

public class Vehiculo {private int precio;

void definir_precio_bajo() {precio = 12000;

} void mostrar() {

System.out.println( " Precio:" + precio);

}}

Page 18: Indice Introducción a Java (I). Indice Índice Tipos de datos y operadores Entradas y Salidas básicas Sentencias de control Clases 2.

Indice

Matrices (IV)• Para obtener el ancho de una matriz:

Nombre.length. Ejemplo:String nombres[] = new String[3];nombres[0] = new String(“Antonio”);System.out.println( nombres.length ); // Muestra el número 3

• En comparación con C/C++ la copia de matrices completas resulta muy sencilla:

int Origen[] = { 200, 400, 600 }; int Destino[] = { 10, 20, 30 }; Destino = Origen; System.out.println( Destino[0] ); System.out.println( Destino[1] );

• Al intentar acceder a un elemento que está fuera del rango de la matriz se genera un ArrayIndexOutOfBoundsException 18

200

400

Page 19: Indice Introducción a Java (I). Indice Índice Tipos de datos y operadores Entradas y Salidas básicas Sentencias de control Clases 2.

Indice

Matrices multidimensionales• Utilizamos una pareja de corchetes ([]) para cada

dimensión. En el caso de una matriz bidimensional un ejemplo sería:

int Lista[][] = new int[filas][columnas];

• Java le permite no tener que especificar todas las dimensiones al principio (con el primer new). Al menos tiene que especificar la dimensión más significativa (más a la izquierda). Además puede hacer que las dimensiones siguientes (menos significativas) difieran. El siguiente ejemplo crea una matriz en la que la primera fila tiene tres columnas y la segunda fila tiene cinco:

int M[][] = new int[2][];M[0] = new int[3];M[1] = new int[5];

19

Page 20: Indice Introducción a Java (I). Indice Índice Tipos de datos y operadores Entradas y Salidas básicas Sentencias de control Clases 2.

Indice

Operadores aritméticos

– Suma: +– Resta: -– Producto: *– División: /– Módulo: % (se puede aplicar a coma flotante y a

int)

– Incremento: ++ (a++ es equivalente a: a=a+1)

– Decremento: -- (a-- es equivalente a: a=a-1)

– Suma y asignación:+= (a+=3 es equivalente a: a=a+3)

– Resta y asignación:-= (a-=3 es equivalente a: a=a-3)

20

Page 21: Indice Introducción a Java (I). Indice Índice Tipos de datos y operadores Entradas y Salidas básicas Sentencias de control Clases 2.

Indice

Operadores relacionales• El resultado de los operadores relacionales es un valor boolean

(true o false):– Igual a: == (no confundirlo con el operador de asignación)

– Distinto de: !=– Mayor que, mayor o igual: >, >=– Menor que, menor o igual: <, <=

• Ejemplo 1:int a = 5, b = 2;boolean c = a >= b;

• Ejemplo 2:float a = 3;if (a == 3)

System.out.println( “El valor es:” + a);

21

Page 22: Indice Introducción a Java (I). Indice Índice Tipos de datos y operadores Entradas y Salidas básicas Sentencias de control Clases 2.

Indice

¿Qué ocurre con String?• A menudo necesitamos comparar cadenas de caracteres, para saber si

una es lexicográficamente igual, mayor o menor que otra. El ejemplo típico es ordenar una lista de nombres

• Ya sabemos que String no es un tipo simple, sino que es una clase. Para ayudarnos en la comparación tenemos los métodos compareTo y compareToIgnoreCase. Podemos saber el orden de las cadenas en función de lo que devuelvan los métodos:

String j = "Belén", k = "Susana", m = "Belén", n = "Antonio"; if (j.compareTo(m) == 0) System.out.println( j + " es igual a " + m); if (j.compareTo(k) < 0) System.out.println( j + " es menor que " + k); if (j.compareTo(n) > 0) System.out.println( j + " es mayor que " + n);

• Existe también el método equals( String ), que devuelve true si las cadenas son iguales. Hay otra versión equalsIgnoreCase(String)

22

Belén es igual a Belén

Belén es menor que Susana

Belén es mayor que Antonio

Page 23: Indice Introducción a Java (I). Indice Índice Tipos de datos y operadores Entradas y Salidas básicas Sentencias de control Clases 2.

Indice

Operadores lógicos

• Operan solamente con valores booleanos:– Conjunción (Y): &&– Disyunción inclusiva (O): ||– Negación: !

• Ejemplo: int edad = 17; float nota = 6f; boolean mayoria_edad = edad >= 18; if (mayoria_edad && nota >= 5) System.out.println( "aprobado" ); if (!mayoria_edad) System.out.println( "Le falta(n) " + (18-edad) + " año(s)" );

23

Page 24: Indice Introducción a Java (I). Indice Índice Tipos de datos y operadores Entradas y Salidas básicas Sentencias de control Clases 2.

Indice

Entradas y Salidas básicas

Page 25: Indice Introducción a Java (I). Indice Índice Tipos de datos y operadores Entradas y Salidas básicas Sentencias de control Clases 2.

Indice

Streams (I)• Cualquier programa realizado en Java que necesite llevar a cabo una operación de

I/O lo hará a través de un stream. • Un stream, cuya traducción literal es "flujo", es una abstracción de todo aquello que

permite introducir o extraer información. Así, un stream de teclado es un flujo de entrada para el programa y un stream de pantalla es un flujo de salida del programa

25

Input:Teclado

Output:Pantalla

La vinculación de este stream al dispositivo físico (teclado, pantalla, impresora, etc.) la hace el sistema de entrada y salida de Java.

Page 26: Indice Introducción a Java (I). Indice Índice Tipos de datos y operadores Entradas y Salidas básicas Sentencias de control Clases 2.

Indice

Streams (II)• El paquete System define tres clases:

– in (entrada estándar)

– out (salida estándar)

– err (salida de errores estándar)

• La escritura hacia pantalla se hace con System.out

System.out.println(“Hola Mundo”); // Añade nueva línea al final System.out.print(“Adios”); // NO añade nueva línea al final

• La lectura desde teclado se hace con System.in

26

Page 27: Indice Introducción a Java (I). Indice Índice Tipos de datos y operadores Entradas y Salidas básicas Sentencias de control Clases 2.

Indice

Stream de entrada por teclado• Para manejar entradas por teclado tenemos que crear un BufferedReader a partir de System.in:

import java.io.*;

public class inicio { public static void main(String[] args) throws IOException {

String cadena;BufferedReader entrada;

entrada = new BufferedReader(new InputStreamReader(System.in)); // Crear objeto de entrada

System.out.println("Escribe tu nombre:");cadena = entrada.readLine(); //leemos cadena de caracteres mediante readLine()

}}

• Condiciones previas a la creación de un BufferedReader:– Tengo que importar las clases que uso (BufferedReader y InputStreamReader), que están en el paquete java.io, por

medio de import.– Tengo que poner “throws IOException” en la función que usa BufferedReader (ya se explicará más adelante el manejo de

excepciones).• Una vez creado el objeto de entrada para teclado, mediante BufferedReader, puedo leer la entrada por

teclado mediante una llamada a objeto.readLine() (la entrada termina al pulsar Enter). No olvidar que esta función devuelve un String, es decir, cualquier cosa que el usuario teclea se almacena como una cadena, sea “pedro” o “3420”. Java es un lenguaje fuertemente tipado y si queremos que lo tecleado se convierta en un número habrá que hacer posteriormente una conversión mediante métodos, como veremos en el siguiente ejemplo.

27

Page 28: Indice Introducción a Java (I). Indice Índice Tipos de datos y operadores Entradas y Salidas básicas Sentencias de control Clases 2.

Indice

Un ejemplo entrada por teclado y conversiónpublic static void main(String[] args) throws IOException {

double PI = 3.1416, radio;int area_int;String c;

/* Creo el objeto 'entrada', es un lector de entradas por teclado */BufferedReader entrada = new BufferedReader( new InputStreamReader(System.in));

System.out.print( "Escriba el radio: " );c = entrada.readLine(); // Leo un String de la entrada de teclado

radio = Double.parseDouble( c ); // Convierto el String en double radio

System.out.println( "El área es: " + radio * radio * PI);

area_int = (int) (radio * radio * PI); // Calculo el área entera del círculo. Hago castingSystem.out.println( "El área (entera) es: " + area_int);

}

• Desde un String existen conversiones a otros tipos: Integer.parseInt( cadena ) o Float.parseFloat( cadena). La conversión inversa utiliza String.valueOf( numero).

• Para que todo funcione: una vez que se ha dado la orden de ejecución, se debe hacer click en la ventana de mensajes, de esta forma la ventana de mensajes obtiene el foco de teclado. A partir de aquí todo lo que se teclea va a dicha ventana.

28

Page 29: Indice Introducción a Java (I). Indice Índice Tipos de datos y operadores Entradas y Salidas básicas Sentencias de control Clases 2.

Indice

Sentencias de control

Page 30: Indice Introducción a Java (I). Indice Índice Tipos de datos y operadores Entradas y Salidas básicas Sentencias de control Clases 2.

Indice

Introducción• Las sentencias de control nos ayudan a que el flujo de ejecución del programa

deje de tener un carácter lineal.• Ejemplos de sentencias de control en la vida cotidiana:

– Ejemplo 1:• Si el cheque es correcto y hay fondos

– Entonces pagar• Si no:

– No pagar

– Ejemplo 2:• Mientras la salsa no este densa:

– Calentar y remover

– Ejemplo 3:• Siga adelante• Cuando llegue a la plaza:

– Si es hora punta» Entonces tuerza a la derecha

– Si no:» Siga todo recto

• Vamos a ver los siguientes tipos de sentencias de control:– Selección– Iteración– Salto 30

Page 31: Indice Introducción a Java (I). Indice Índice Tipos de datos y operadores Entradas y Salidas básicas Sentencias de control Clases 2.

Indice

if / else (I)• La sentencia básica para realizar bifurcaciones o

ramificaciones. Formato:if (condición)

sentencia 1;[else

sentencia 2]

• La condición es una expresión booleana. Si es true, se hace la sentencia 1; si es false, se hace la sentencia 2 (si existiese)

• Ejemplo:int a = 3, b = 9, c;if (a < b && a != 0)

c = b – a;else

c = a – b; 31

Precaución:

La tabulación es fundamental para

realizar código legible

Page 32: Indice Introducción a Java (I). Indice Índice Tipos de datos y operadores Entradas y Salidas básicas Sentencias de control Clases 2.

Indice

if / else (II)• Si hay más de una sentencia debemos delimitar los bloques por llaves {}. En el

siguiente ejemplo vamos a determinar las ventajas que tiene un cliente en función de los puntos de su tarjeta de compra:

if (puntos > 1000) { tipo_cliente = "VIP"; descuento = 0.05f;}else { tipo_cliente = "Normal"; descuento = 0.02f;}System.out.println( "Tipo: " + tipo_cliente + "\tDescuento: " + descuento*100 + "%");

• Los condicionales pueden ser anidados, es decir, que uno este dentro de otro. En nuestro ejemplo vamos a añadir otra condición: para los clientes de más de 1000 puntos, si su antigüedad es mayor de 1825 días, les haremos un descuento del 6%:

if (puntos > 1000) { tipo_cliente = "VIP"; descuento = 0.05f; if (antiguedad > 1825) descuento = 0.06f;} 32

Page 33: Indice Introducción a Java (I). Indice Índice Tipos de datos y operadores Entradas y Salidas básicas Sentencias de control Clases 2.

Indice

switch• Formato:

switch ( expresión ) { // expresión: no tiene que ser booleanocase constante1:

secuencia de sentenciasbreak;

case constante2:secuencia de sentenciasbreak;

...default:

secuencia de sentencias}

• No olvidar ‘break’. Pero a veces es adecuado omitirlo:switch ( categoria ) {

case 1:case 2:

porcen = 0.2; // Tanto para 1 como para 2 break;

case 3:porcen = 0.15;break;

default:porcen = 0.1;

}

33

Page 34: Indice Introducción a Java (I). Indice Índice Tipos de datos y operadores Entradas y Salidas básicas Sentencias de control Clases 2.

Indice

while• Formato:

while (condición)

Sentencia• La sentencia puede ser un bloque delimitado por llaves ({}). El bucle se realiza

mientras la condición sea cierta• Ejemplo en el que modificamos un vector de números, de tal modo que ponemos

el cuadrado del número que antes estuviese: double serie[] = {23, 4, 36, 9}; int i = 0; while ( i < serie.length ) { System.out.print( "Posición: " + i + "\t Anterior: " + serie[i] ); serie[i] = serie[i] * serie[i]; System.out.println( "\t Cuadrado: " + serie[i] ); i++; }

34

Posición: 0 Anterior: 23.0 Cuadrado: 529.0

Posición: 1 Anterior: 4.0 Cuadrado: 16.0

Posición: 2 Anterior: 36.0 Cuadrado: 1296.0

Posición: 3 Anterior: 9.0Cuadrado: 81.0

Bucle

Page 35: Indice Introducción a Java (I). Indice Índice Tipos de datos y operadores Entradas y Salidas básicas Sentencias de control Clases 2.

Indice

for (I)• En la vida cotidiana hay numerosos casos de iteraciones (repeticiones). Por ejemplo, si

alguien tiene que asignar un número a las cinco personas que hay en una habitación haría algo así:

for (el número es 1; mientras que el número sea < 6; incremento el número)Digo en voz alta el número, señalando a la persona correspondiente

• De forma semejante, el formato de for es:for ( inicialización; condición; variación )

Sentencia

• Con un ejemplo puede aclararse. Supongamos que queremos mostrar por pantalla los cuatro primeros números enteros, empezando por el 3:

– La inicialización sería: empezar con el número 3– Condición: mientras que el número sea menor que 7 (es aquello que debe cumplirse para poder

volver a repetir la sentencia)– Variación: incrementar en uno el número– Sentencia (aquello que se debe iterar o repetir, en nuestro ejemplo 4 veces): mostrar el número por

pantalla• Ejemplo:

int i;for ( i = 3; i < 7; i++)

System.out.println( i );

• Nos podemos saltar la inicialización (empieza en el valor previo)int i = 3;for ( ; i < 7; i++)

System.out.println( i ); 35

Page 36: Indice Introducción a Java (I). Indice Índice Tipos de datos y operadores Entradas y Salidas básicas Sentencias de control Clases 2.

Indice

for (II)• Vamos a ver paso a paso como actua la

iteración

• Ejemplo:int i;for ( i = 1; i < 3; i++)

System.out.println( i );

• Al observar la ejecución paso a paso es importante recordar:– Siempre se evalúa la condición ANTES

de ejecutar la sentencia– DESPUÉS de la sentencia siempre se

realiza la variación

• Se pueden iterar varias variables, para lo cual necesitamos comas: for(i=0, k=5; i < 5; i++, k=k+5)

36

1. INICIO: la variable i se inicia a 12. CONDICIÓN: se comprueba la

condición: ¿ i<3 ? SI3. SENTENCIA: se ejecuta la

sentencia println4. VARIACIÓN: al terminar el bucle,

se incrementa i. Ahora vale 25. CONDICIÓN: se comprueba la

condición: ¿ i<3 ? SI6. SENTENCIA: se ejecuta la

sentencia println7. VARIACIÓN: al terminar el bucle,

se incrementa i. Ahora vale 38. CONDICIÓN: se comprueba la

condición: ¿ i<3 ? NO, fin del bucle

9. IMPORTANTE: al salir del bucle el valor de i es 3. ¿Cuál sería su valor si la condición fuese i<=3?

Page 37: Indice Introducción a Java (I). Indice Índice Tipos de datos y operadores Entradas y Salidas básicas Sentencias de control Clases 2.

Indice

for (III)• Igual que los casos anteriores: utilizan {} para acotar conjuntos de sentencias y además son

anidables.• Ejemplo en el que se calcula la media y el máximo de un vector de números:

public static void main(String[] args) { float serie[] = {-8, -12, -4, -14}; float media, sumatorio = 0; int contador; float maximo = serie[0]; // ¿Funcionaria si asignamos el 0?

/*** Hallamos el máximo y sumamos todos los números ***/ for ( contador = 0; contador < serie.length; contador++ ) { if (serie[contador] > maximo) maximo = serie[contador]; sumatorio = sumatorio + serie[contador]; } /*** Calculamos media. Mostramos la media y el maximo ***/ media = sumatorio / contador; System.out.println( "La media es " + media + " y el max es " + maximo); }

• Se pueden clasificar las variables en virtud de su función o uso (hasta ahora las hemos clasificado en virtud del tipo de dato). Entre estos tipos de usos hay dos que son muy comunes y aparecen en nuestro ejemplo:

– Variables contador– Variables sumatorio

37

Page 38: Indice Introducción a Java (I). Indice Índice Tipos de datos y operadores Entradas y Salidas básicas Sentencias de control Clases 2.

Indice

do-while• Formato:

do {Sentencia

} while (condición);

• A diferencia de while, analiza la condición al final del bucle. Por tanto, la sentencia se realiza al menos una vez

• Ejemplo. ¿Qué hace?:int i = 1;do {

System.out.println( i*i*i );i++;

} while ( i < 3 );

• do-while es muy útil en la gestión de menús. El diseño sería:do {

Muestro las opciones de menúSolicito la opción por tecladoswitch (opcion) {

En función de la opción elegida realizo una u otra acción}

} while (la opción no sea “Salir”);

• A continuación puede verse un ejemplo de gestión de menú para una calculadora38

Page 39: Indice Introducción a Java (I). Indice Índice Tipos de datos y operadores Entradas y Salidas básicas Sentencias de control Clases 2.

Indice

Calculadora public static void main(String[] args) throws IOException { char opcion; String cadenaTeclado; double operando1 = 0, operando2 = 0; /* Creo el obj. 'entrada', es un lector de entradas por teclado */ BufferedReader entrada = new BufferedReader( new

InputStreamReader(System.in));

do { /********* Mostrar menu y pedir opcion por teclado ****/ System.out.print("\r\n S - Suma\r\n R - Resta\r\n P - Producto" + "\r\n

D - División\r\n Q - Salir\r\n Su opción:"); cadenaTeclado = entrada.readLine(); // Teclado opcion = cadenaTeclado.charAt( 0 ); // Conv a char

/********* Si la opción no es salir, solicito operandos ***/ if ( opcion != 'Q' && opcion != 'q') { System.out.print( "Número 1: " ); cadenaTeclado = entrada.readLine(); // Teclado operando1 = Double.parseDouble( cadenaTeclado ); // Conv System.out.print( "Número 2: " ); cadenaTeclado = entrada.readLine(); // Teclado operando2 = Double.parseDouble( cadenaTeclado ); // Conv }

39

/**** En función de la opción: opero o salgo ***/

switch (opcion) { case 's': case 'S': System.out.print( operando1 +

operando2 ); break; case 'r': case 'R': System.out.print( operando1 - operando2 ); break; case 'p': case 'P': System.out.print( operando1 * operando2 ); break; case 'd': case 'D': System.out.print( operando1 / operando2 ); break; case 'q': case 'Q': System.out.print( "Adios" ); break; default: System.out.print( "Opción no disponible" );

} /////////////////////////////// Fin de switch } while (opcion != 'Q' && opcion != 'q'); } //////////////////////////////// Fin de función

Page 40: Indice Introducción a Java (I). Indice Índice Tipos de datos y operadores Entradas y Salidas básicas Sentencias de control Clases 2.

Indice

Salto• Hay sentencias que controlan el flujo de ejecución, de tal forma que

realizan saltos fuera del bloque en el que se encuentran:– break: salta fuera del bucle o switch– return: salta fuera del método

• Un ejemplo con break. Busca un nombre en una lista y, si lo encuentra, sale del bucle:

private static void funcion() { int i = 0; String nombre[] = { "Ana", "Belen", "Juan", "Pedro"}; String nombrBuscado = “Belen"; boolean encontrado = false;

while (i < nombre.length) { if (nombre[i].equals(nombreBuscado)) { System.out.println(nombre_buscado + " está en la posición " + i); encontrado = true; break; } i++; } if (!encontrado) System.out.println("No encontrado");} 40

Page 41: Indice Introducción a Java (I). Indice Índice Tipos de datos y operadores Entradas y Salidas básicas Sentencias de control Clases 2.

Indice

Clases

Page 42: Indice Introducción a Java (I). Indice Índice Tipos de datos y operadores Entradas y Salidas básicas Sentencias de control Clases 2.

Indice

Introducción (I)• Hasta ahora las clases las hemos usado como soporte al método main. A

partir de aquí vamos a adentrarnos en el manejo de clases• Una clase puede entenderse como un modelo o patrón: la representación

abstracta de un conjunto• Un conjunto en la vida cotidiana puede ser definido por sus atributos y/o

por acciones (comportamiento). Por ejemplo:– El conjunto de los mamíferos con aletas– El conjunto de los profesionales en extinción del fuego

• Un bombero en concreto sería una instancia del conjunto de los bomberos

• Cuando definimos el conjunto de los bomberos no hacemos referencia a ningún bombero en concreto, de la misma manera, cuando definimos una clase no hacemos referencia ni creamos un objeto o instancia de la clase

42

Page 43: Indice Introducción a Java (I). Indice Índice Tipos de datos y operadores Entradas y Salidas básicas Sentencias de control Clases 2.

Indice

Introducción (II)• Del mismo modo que ocurre con los conjuntos de la vida cotidiana, las clases se definen por

sus atributos y/o métodos (funciones que definen el comportamiento de la clase). Por ahora vamos a empezar con los atributos.

• Veamos el siguiente ejemplo en el que la clase Inicio hace una instancia de la clase Circulo:

• Creamos la clase Circulo. Es importante entender que la sentencia “Circulo a;” NO CREA un objeto, sino que crea una referencia o etiqueta (vacía o nula). Por ello, si queremos acceder al atributo “radio” para asignarle un valor (23), el compilador nos dará un mensaje de error. SOLO se crea un objeto si se utiliza new. Lo correcto sería:

Circulo a;a = new Circulo(); // O bien: Circulo a = new Circulo();a.radio = 23; 43

/******** Circulo.java ********/

package figuras.dominio;

public class Circulo {

public double radio;

public double PI = 3.1416;

}

/********* Inicio.java *****/

package figuras.inicio;

import figuras.dominio.Circulo;

public class Inicio {

public static void main(String[] args) {

Circulo a; // ERROR

a.radio = 23;

}

}

Page 44: Indice Introducción a Java (I). Indice Índice Tipos de datos y operadores Entradas y Salidas básicas Sentencias de control Clases 2.

Indice

Introducción (III)• El error anterior era un error en tiempo de compilación. La mayor parte de

IDEs nos darán un mensaje del estilo “variable no inicializada” antes de compilar, es decir, el entorno de desarrollo ha detectado que no hay un objeto, que la etiqueta no hace referencia a un objeto.

• Podemos “engañar” a la mayor parte de los IDEs con el siguiente código, que se puede compilar sin errores:

Circulo a = null;

a.radio = 23; // Línea número 7

• Decimos “engañar” ya que este código hará que el IDE no nos muestre el error en tiempo de compilación. Pero el problema es el mismo: no hay objeto para la etiqueta “a”.

• El error surge en tiempo de ejecución: java.lang.NullPointerException at figuras.inicio.Inicio.main(Inicio.java:7)

• Este es el error más frecuente en programación Java (y en otros lenguajes como C/C++) y siempre indica lo mismo: tratamos de acceder a un atributo o método del objeto, pero ocurre que no hay objeto

44

Page 45: Indice Introducción a Java (I). Indice Índice Tipos de datos y operadores Entradas y Salidas básicas Sentencias de control Clases 2.

Indice

Introducción (IV)

• Una clase es un patrón o modelo, no crea un objeto. Se crea un objeto con new

• Cada objeto tiene sus atributos o variables miembro (hay una excepción a esta regla: los atributos static).

• En el siguiente ejemplo, el primer círculo tiene un atributo radio que es diferente al mismo atributo del segundo círculo. Es más, ocupan posiciones de memoría diferentes

public static void main(String[] args) { Circulo a = new Circulo(); Circulo b = new Circulo(); a.radio = 23; b.radio = 35.6; }

45

Page 46: Indice Introducción a Java (I). Indice Índice Tipos de datos y operadores Entradas y Salidas básicas Sentencias de control Clases 2.

Indice

El primer método• Vamos a introducir un método en nuestra clase “Circulo”, que

simplemente muestra el área:

• Una llamada al método implica un SALTO: el ordenador pasa a ejecutar el código del método y una vez que este termina se devuelve el control a main

• Las flechas muestran los saltos que da el control de ejecución del programa• El método muestra los atributos de SU OBJETO

46

public class Circulo {

public double radio;

public double PI = 3.1416;

public void mostrarArea() {

System.out.println( radio*radio*PI );

}

}

public class Inicio {

public static void main(String[] args) {

Circulo a = new Circulo();

Circulo b = new Circulo();

a.radio = 23;

b.radio = 35.6;

a.mostrarArea();

b.mostrarArea();

}

}

Page 47: Indice Introducción a Java (I). Indice Índice Tipos de datos y operadores Entradas y Salidas básicas Sentencias de control Clases 2.

Indice

Formato de los métodos• El formato de los métodos es:

Tipo_acceso tipo_devuelto Nombre_método( parámetros ) {Cuerpo del método

}

• El tipo de acceso puede ser:– Para clases que están en el mismo paquete (por defecto: public):

• public: se puede llamar al método desde fuera de la clase• protected: se puede llamar al método desde fuera de la clase • private: no se accede desde fuera de la clase

– Para clases que están en diferentes paquetes (por defecto: protected):• public: se puede llamar al método desde fuera de la clase• protected: no se accede desde fuera de la clase• private: no se accede desde fuera de la clase

• El “tipo devuelto” es el tipo de dato que devuelve el método

47

Page 48: Indice Introducción a Java (I). Indice Índice Tipos de datos y operadores Entradas y Salidas básicas Sentencias de control Clases 2.

Indice

Devolviendo valores• En nuestro ejemplo calculamos el área en println, pero esto no es muy inteligente. Ya que si

necesitamos de nuevo el área, tenemos que volver a calcularla. Lo lógico es realizar el cálculo EN UN ÚNICO MÉTODO y que este método devuelva el resultado. En el siguiente ejemplo vamos a crear un método público que devuelve el área:

public class Circulo { public double radio; public double PI = 3.1416; public void mostrarArea() { System.out.println( getArea() ); } public double getArea() { return radio*radio*PI; }}

• La flecha muestra como se transfiere el control de ejecución. La sentencia return es una orden de salto.

• Error de principiante: no hay coherencia entre el tipo que declaramos que vamos a devolver y el tipo efectivamente devuelto. En nuestro ejemplo hay coherencia:

– Declaramos que vamos a devolver double al escribir “public double obtener_area() ...”– Efectivamente devolvemos double, el resultado de multiplicar variables de tipo double como radio y PI

48

Page 49: Indice Introducción a Java (I). Indice Índice Tipos de datos y operadores Entradas y Salidas básicas Sentencias de control Clases 2.

Indice

Introducción a los parámetros• Veamos el siguiente ejemplo de función que calcula y devuelve el

cuadrado de un número:double cuadrado() {

return 5*5;}

• Esto es evidentemente un absurdo, sólo nos sirve si el número es 5. Resulta más lógico que el método calcule con independencia de cual es el número base. Para ello, el método debe tener parámetros:

public class Param {public static void main(String[] args) {

double h = cuadrado(3); // Argumentos System.out.println( h ); } /*** Devuelve el cuadrado ***/ public static double cuadrado( double base ) { // Parámetros return ( base * base ); }}

49

El parámetro “base” recibe el argumento 3

Page 50: Indice Introducción a Java (I). Indice Índice Tipos de datos y operadores Entradas y Salidas básicas Sentencias de control Clases 2.

Indice

Parámetros: los nombres son lo de menos

• El principiante poco informado puede pensar que los nombres de los parámetros dependen de los nombres de los argumentos. Puede creer que si el argumento se llama “X”, el parámetro debe llamarse “X”:

public static void main(String[] args) {double largo = 3, ancho = 2;

double h = getArea( largo, ancho); System.out.println( h );}

public static double getArea(double largo, double ancho) { return (largo * ancho);}

• Este personaje desconoce que los nombres son indiferentes, lo que importa es que el parámetro, se llame como se llame, recibe el contenido del argumento (más adelante distinguiremos llamadas por valor de llamadas por referencia). La aprueba es que el método anterior actúa igual si se escribiese así:

public static double getArea(double PinPanPun, double segundo) { return (PinPanPun * segundo);}

50

Page 51: Indice Introducción a Java (I). Indice Índice Tipos de datos y operadores Entradas y Salidas básicas Sentencias de control Clases 2.

Indice

Una pequeña excepción a la regla anterior• Hemos visto que los nombres son lo de menos en el ejemplo de las variables “ancho” y “largo” (no

hay conflicto porque tienen ámbitos de vida independientes)• Bien, pero la excepción es: “salvo cuando hay conflicto de nombres con un atributo de la clase”,

aquí hay conflicto con los ámbitos de vida. Supongamos que usamos de parámetros para almacenar los valores en atributos de un objeto:

public class Camino {private double largo;

public void setLargo( double largo ) { largo = largo; }}

• Esto es un error absurdo: almacenamos el valor de la variable parámetro “largo” en ella misma (no en el atributo). Con el agravante de que ese valor se pierde al terminar el método.

• Lo que queremos es almacenar el valor en el atributo, para lo cual usaremos la palabra reservada “this”:

public void setLargo( double largo ) { this.largo = largo; }• “this” es una forma de hacer referencia al objeto, es la forma que tiene el propio objeto de decir

“yo”. Este nombre se usa para hacer referencia a atributos o métodos del objeto. Resumiendo, en nuestro ejemplo:

– this.largo: variable atributo de la clase– largo: variable parámetro

• Volveremos más adelante sobre “this” y veremos por qué es incompatible con su uso dentro de métodos static

51

Page 52: Indice Introducción a Java (I). Indice Índice Tipos de datos y operadores Entradas y Salidas básicas Sentencias de control Clases 2.

Indice

Parámetros: encapsulando• En nuestro ejemplo del círculo podemos acceder a los atributos de “Circulo”

directamente desde fuera de la clase:Circulo a = new Circulo();a.radio = 3;

• Cambiemos de forma de trabajar. Vamos a hacer que sólo se pueda acceder a los datos por medio de los métodos. Esto implica que debemos poner métodos que devuelvan valores (usan return, get) y otros que asignen valores (usan parámetros, set):

public class Circulo { private double radio; private double PI = 3.1416;

public double getArea() { return radio * radio * PI; } public void setRadio(double nuevoRadio) { radio = nuevoRadio; } public double getRadio() { return radio; }}

52

Reglas importantes:

• Encapsular: desde fuera de la clase sólo se accede a los métodos públicos. No se accede directamente a los datos

• Modularizar: separar procesamiento de datos de su presentación. Un ejemplo es que los cálculos se hacen en métodos diferentes a la presentación de datos (incluso, lo que es aún mejor, en clases diferentes). También es una forma de hacer software cohesivo

Page 53: Indice Introducción a Java (I). Indice Índice Tipos de datos y operadores Entradas y Salidas básicas Sentencias de control Clases 2.

Indice

Encapsular• En la ingeniería del software se especifican reglas que deben seguirse

para ayudarnos a realizar software robusto (no proclive a fallos), fácilmente entendible y de fácil mantenimiento (modificaciones poco costosas)

• El principio de “Encapsulamiento” (ocultamiento de información) nos indica (entre otras cosas) que debemos hacer que los detalles de la clase estén ocultos para el exterior (también se denomina implementación encapsulada). Una aplicación de este principio implica que los atributos serán privados y sólo se puede acceder a ellos desde los métodos de la clase

• Ventaja: desde el código de la clase controlamos el acceso a los atributos. En caso de fallo o modificación del código, el programador comprueba los métodos de la clase y no tiene que revisar todo el código de los otros archivos

• Los métodos públicos son el intermediario entre los datos y los otros objetos

53

Método 1

Método 2

Datos

Objeto

Llamada

Los métodos públicos de la clase son el

interfaz de la clase

Page 54: Indice Introducción a Java (I). Indice Índice Tipos de datos y operadores Entradas y Salidas básicas Sentencias de control Clases 2.

Indice

Un ejemplo de encapsulamiento• Supongamos que tenemos una clase que representa los productos de un

comercio, en el que hay un precio normal y un precio rebajado:public class Producto { private float precio; private float precioRebajado; public void setPrecioRebajado( float porcentajeRebaja ) { precioRebajado = precio * (1-porcentajeRebaja); }

…}

• ¿Por qué decimos que es una implementación encapsulada? Por dos razones ligadas:

– Encapsular datos: sólo se accede al atributo privado “precioRebajado” por medio de un método público de la clase

– Encapsulamos el cálculo: la forma de calcular el dato queda oculta al exterior de la clase. Supongamos que debemos cambiar la forma de calcular el precio rebajado (bien por corregir un error de programación o bien por cambiar la política de rebajas), entonces sólo tendremos que cambiar el método “setPrecioRebajado()”.

54

Page 55: Indice Introducción a Java (I). Indice Índice Tipos de datos y operadores Entradas y Salidas básicas Sentencias de control Clases 2.

Indice

Un ejemplo de NO encapsulamiento• Tomemos el ejemplo anterior y supongamos que la clase es así:public class Producto { public float precio; public float precioRebajado;

• Estoy permitiendo el acceso externo a los datos del producto. Por tanto en una clase externa se podría escribir algo como esto:

static public void main(…) { Producto a = new Producto();

a.precio = 25.5;a.precioRebajado = a.precio *0.80;…Producto b = new Producto();b.precio = 19;b.precioRebajado = b.precio *0.80;…

• La irracionalidad suele ser costosa. Si tenemos que cambiar nuestra política de rebajas tendremos que cambiar todas las líneas de código donde calculamos el precio rebajado para cada producto, en una implementación encapsulada sólo tenemos que cambiar el método setPrecioRebajado() de la clase Producto

• En una implementación encapsulada tendríamos que modificar un bloque de código, no N bloques de código.

55

Page 56: Indice Introducción a Java (I). Indice Índice Tipos de datos y operadores Entradas y Salidas básicas Sentencias de control Clases 2.

Indice

Modularizar• Un diseño modular se basa en la conocida estrategia de

“divide y vencerás”. Descomponer de forma lógica la aplicación

• Para conseguir la modularidad debemos hacer que nuestros componentes de software sean especialistas

• En un ejemplo básico y típico separaremos:– Inicio de aplicación: paquete y clase donde está main()– Clases del dominio de problema: por ejemplo, paquete

figuras.dominio con las clases Circulo, Rectangulo, etc– Clases de presentación: paquete para el interfaz de la aplicación

(menú de opciones, presentación de clases de dominio, etc.)– Clases para persistencia o almacenamiento en base de datos,

archivos, etc.

56

Page 57: Indice Introducción a Java (I). Indice Índice Tipos de datos y operadores Entradas y Salidas básicas Sentencias de control Clases 2.

Indice

Un ejemplo de modularización• En el siguiente ejemplo separamos las clases del dominio (en este caso

Circulo.java) de la clase responsable de la presentación:

57

package figuras.dominio;

public class Circulo { private double radio; private double PI = 3.1416;

public Circulo() { } public Circulo( double nuevoRadio ) { setRadio( nuevoRadio ); } public double getArea() { return radio * radio * PI; } public void setRadio( double radio ) { this.radio = radio; } public double getRadio() { return radio; } public String toString() { return "Radio: " + radio + " Area: " +

getArea(); }}

package figuras.presentacion;

import figuras.dominio.*;

public class VistaFiguras {

public static void mostrar( Circulo cir ) { System.out.println( cir.toString() ); }

public static void mostrar( Rectangulo rec ) { System.out.println( rec.toString() ); }}

¿Cómo se haría un main() que use estas clases?

Page 58: Indice Introducción a Java (I). Indice Índice Tipos de datos y operadores Entradas y Salidas básicas Sentencias de control Clases 2.

Indice

Constructores• Un constructor es un método al que se llama cuando se crea un objeto con new:

– Sólo son llamados inmediatamente después de la creación del objeto– Tienen el mismo nombre que la clase y no devuelven valores– Son públicos

• En nuestro ejemplo vamos a crear un constructor que inicia el radio con 1: Circulo() { radio = 1; }

• Pero en muchas ocasiones al crear un objeto nos interesa inicializar atributos (en nuestro caso el radio). Para ello, los constructores admiten parámetros:

class Circulo {private double radio;private double PI = 3.1416;

public Circulo( double nuevoRadio ) { setRadio( nuevoRadio ); } public void setRadio( double radio ) { this.radio = radio; }

• Utilizamos el nombre de “constructores” por ser el más extendido, pero no confundirse: el constructor no construye el objeto; sino que es invocado inmediatamente después de la construcción

• Si no implementamos un constructor, Java pone uno por defecto (constructor vacío)

58

Circulo a = new Circulo();

...

Circulo a = new Circulo(21);

...

Page 59: Indice Introducción a Java (I). Indice Índice Tipos de datos y operadores Entradas y Salidas básicas Sentencias de control Clases 2.

Indice

finalize()• En lenguajes como C++ la memoria ocupada por los objetos creados por new es

liberada manualmente, mediante el operador delete . En Java la orientación es diferente: tiene un procedimiento automático de “recogida de basura”. Este procedimiento examina las referencias y el ámbito, cuando considera que un objeto no va a ser utilizado lo elimina, es decir, libera la memoria que ocupa

• Inmediatamente antes de que se libere la memoria se invoca automáticamente al método finalize(). El programador puede implementarlo cuando desee realizar una acción antes de la eliminación del objeto:

protected void finalize() {System.out.println( “Adios” );

}

• Téngase en cuenta que no se puede garantizar el momento exacto en el que el programa invocará al método:

– El procedimiento de recogida de basura no se ejecuta siempre que se deja de utilizar un objeto, sino que se ejecuta de manera esporádica

– Además cada interprete de Java tiene su procedimiento de recogida de basura• Por tanto, no se puede confundir con los destructores de C++. Java no tiene el

concepto de destructor

59

Page 60: Indice Introducción a Java (I). Indice Índice Tipos de datos y operadores Entradas y Salidas básicas Sentencias de control Clases 2.

Indice

Sobrecarga de métodos• Java nos permite tener métodos con el mismo

nombre y que se diferencian por sus argumentos:

60

Al llamar a un método, Java busca la versión del método que coincide con los argumentos de la llamada

package figuras.presentacion;

import figuras.dominio.*;

public class VistaFiguras {

public static void mostrar( Circulo cir ) { System.out.println( cir.toString() ); }

public static void mostrar( Rectangulo rec ) { System.out.println( rec.toString() ); }}

¿Por qué hace falta hacer import de las clases del paquete “figuras.domino”? Porque están en un paquete diferente

que “VistaFiguras”

Page 61: Indice Introducción a Java (I). Indice Índice Tipos de datos y operadores Entradas y Salidas básicas Sentencias de control Clases 2.

Indice

Sobrecarga de constructores• Los constructores, como cualquier otro método, pueden ser sobrecargados:

class Circulo {private double radio;private double PI = 3.1416;

/****** Constructores sobrecargados ***/public Circulo() { }

public Circulo( double nuevoRadio ) { setRadio( nuevoRadio ); } public Circulo( Circulo circulo ) { setRadio( circulo.getRadio() ); } ...}

• Observe que el último constructor define el radio a partir del radio de otro círculo, que se ha pasado como argumento

• ¿ Cómo sería la llamada que ejecutase dicho constructor?

61

Page 62: Indice Introducción a Java (I). Indice Índice Tipos de datos y operadores Entradas y Salidas básicas Sentencias de control Clases 2.

Indice

El proyecto de las figuras. Los puntospackage figuras.dominio;

public class Punto { private int x; private int y;

public Punto(int x, int y) { setPunto(x, y); } public Punto(Punto p) { setPunto(p ); } public void setPunto(int x, int y) { this.x = x; this.y = y; } public void setPunto(Punto p) { x = p.getX(); y = p.getY(); }

public int getX() { return x; } public int getY() { return y; }

public String toString() { return "(" + x + "," + y + ")"; }}

62

Aspectos a resaltar:

• Encapsulamiento

• Sobrecarga de constructores• Constructor “de copia”: Punto(Punto p). Con

este constructor se hace un punto que es una copia (tiene la misma posición) que el objeto que se pasa como argumento (p)

Page 63: Indice Introducción a Java (I). Indice Índice Tipos de datos y operadores Entradas y Salidas básicas Sentencias de control Clases 2.

Indice

El proyecto de las figuras. Los círculos (I)package figuras.dominio;

public class Circulo { private Punto posicion; private double radio; static final public double PI = 3.1416;

public Circulo() { } public Circulo( double nuevoRadio, Punto nuevaPosicion ) { setRadio( nuevoRadio ); setPosicion( nuevaPosicion ); } public Circulo( double nuevoRadio, int posicionX, int posicionY ) { setRadio( nuevoRadio ); posicion = new Punto( posicionX, posicionY ); } public Circulo( Circulo circulo ) { setRadio( circulo.getRadio() ); setPosicion( circulo.getPosicion()); } public void setRadio( double radio ) { this.radio = radio; } public void setPosicion( Punto posicion ) { this.posicion = posicion; } public Punto getPosicion() { return posicion; } public double getRadio() { return radio; } public double getArea() { return radio * radio * PI; } public String toString() { return "Radio: " + radio + " Posicion: " + posicion.toString() +

" Area: " + getArea(); }} 63

Aspectos a resaltar:

• Encapsulamiento

• Un atributo (posicion) es un objeto de otra clase (Punto)

• PI es static (lo comentaremos más adelante)

• PI es final: es una constante, no puede cambiarse. Esto evita modificaciones accidentales por parte del programador

• Sobrecarga de constructores

• Constructor “de copia”: Circulo(Circulo circulo). Con este constructor se hace un círculo que es una copia del objeto que se pasa como argumento (circulo)

• ¿Por qué no hace falta import de la clase “Punto”? Porque está en el mismo paquete

Page 64: Indice Introducción a Java (I). Indice Índice Tipos de datos y operadores Entradas y Salidas básicas Sentencias de control Clases 2.

Indice

El proyecto de las figuras. Los círculos (II)

• Interesa distinguir dos constructores:public Circulo( double nuevoRadio, Punto nuevaPosicion ) {

setRadio( nuevoRadio ); setPosicion( nuevaPosicion ); } public Circulo( double nuevoRadio, int posicionX, int posicionY ) { setRadio( nuevoRadio ); posicion = new Punto( posicionX, posicionY ); }

• En el primer caso recibimos un objeto (nuevaPosicion), que “almacenamos” en el atributo “posicion”. No tiene nada de extraño

• En el segundo caso no se recibe un objeto, sino que recibimos dos variables (“posicionX” y “posicionY”), sin embargo la clase de los círculos requiere tener un objeto para el atributo “posicion”. Por ello, se tiene que crear (new) el objeto de la clase Punto.

64

Page 65: Indice Introducción a Java (I). Indice Índice Tipos de datos y operadores Entradas y Salidas básicas Sentencias de control Clases 2.

Indice

El proyecto de las figuras. La visualizaciónpackage figuras.presentacion;

import figuras.dominio.*;

public class VistaFiguras {

public static void mostrar( Circulo cir ) { System.out.println( cir.toString() ); }

public static void mostrar( Rectangulo rec ) { System.out.println( rec.toString() ); }}

65

Aspectos a resaltar:

• Modularidad: separamos la presentación (“VistaFiguras”) de las clases de dominio de problema (puntos, círculos, etc.)

• Sobrecarga de constructores

• ¿Por qué hace falta import de las clases del paquete “figuras.dominio”? Porque dichas clases están en un paquete diferente al de “VistaFiguras”

Page 66: Indice Introducción a Java (I). Indice Índice Tipos de datos y operadores Entradas y Salidas básicas Sentencias de control Clases 2.

Indice

El proyecto de las figuras. El iniciopackage figuras.inicio;import figuras.dominio.*;import figuras.presentacion.*;

class Inicio { public static void main(String[] args) { Circulo primero = new Circulo( 23, 2, 3 ); Circulo copia = new Circulo( primero ); Circulo tercero = new Circulo( 17, new Punto(8,9) );

VistaFiguras vista = new VistaFiguras();

vista.mostrar( primero ); vista.mostrar( copia ); vista.mostrar( tercero ); }}

66

Aspectos a resaltar:

• Sobrecarga de constructores

• Usamos constructor de copia

• ¿Por qué hacen falta imports?

• Si hubiera que hacer la clase Rectangulo, ¿cómo sería?

Page 67: Indice Introducción a Java (I). Indice Índice Tipos de datos y operadores Entradas y Salidas básicas Sentencias de control Clases 2.

Indice

Llamadas por valor• Cuando hacemos una llamada a un método, que tiene argumentos que

son tipos simples, se hace una copia del valor y se traslada al parámetro del método. Para que se entienda:

public static void main(String[] args) { /******** Llamada por valor (copia del valor) *****/ double d = 11.5; cuadrado( d ); System.out.println( d );}public static void cuadrado( double num ) { num = num * num;}

• El programa muestra el número 11.5, es decir, la función no ha modificado la variable argumento (d).

• Esto significa que la función “cuadrado()” no modifica el valor de la variable “d”. Modifica una copia de “d”.

67

Copia del valor: 11.5

Page 68: Indice Introducción a Java (I). Indice Índice Tipos de datos y operadores Entradas y Salidas básicas Sentencias de control Clases 2.

Indice

Llamadas por referencia• Cuando los argumentos son objetos (no usamos tipos simples) no se pasa una

copia del objeto, sino que se pasa el propio objeto. Los parámetros del método reciben el objeto (llamada por referencia): public static void main(String[] args) {

Circulo primero = new Circulo( 23, 2, 3 );trasladar( primero, new Punto(111,111) ); // Llamada por referencia

vista.mostrar( primero ); }

public static void trasladar( Circulo c, Punto nuevaPosicion ) { c.setPosicion( nuevaPosicion ); }

• Pasamos a la función trasladar() el circulo “primero” con su nueva posición• La función modifica el argumento (“primero”)

68

Page 69: Indice Introducción a Java (I). Indice Índice Tipos de datos y operadores Entradas y Salidas básicas Sentencias de control Clases 2.

Indice

String es una excepción• Hemos dicho que todas las clases (no los tipos simples)

son pasadas en llamadas por referencia.• String es una excepción: las llamadas son por copia.• En el siguiente ejemplo el método no cambia el

argumento, sigue teniendo el valor “Adios”: public static void main(String[] args) { String despedida = "Adios"; cambiarDespedida( despedida ); // String es una excepción: llamada por valor System.out.println( despedida ); } public static void cambiarDespedida( String mensaje ) { mensaje = "Hasta luego"; }

69

Page 70: Indice Introducción a Java (I). Indice Índice Tipos de datos y operadores Entradas y Salidas básicas Sentencias de control Clases 2.

Indice

Devolución de objetosHemos visto que return puede servir para devolver el valor de una variable de tipo simple. También puede servir para devolver un objeto (no una copia del objeto, sino un objeto). En el siguiente ejemplo los objetos de la clase “Persona” son capaces de clonarse a si mismos.

public class Persona { private String nombre; private int edad; public Persona( String nuevoNombre, int nuevaEdad ) { setPersona( nuevoNombre, nuevaEdad ); mostrarSaludo(); } public void setPersona( String nuevoNombre, int nuevaEdad ) { nombre = nuevoNombre; edad = nuevaEdad; } public persona clonar( ) { Persona p = new Persona( nombre, edad ); System.out.println( nombre + " se ha clonado a si misma/o"); return p; } public void mostrarSaludo() { System.out.println( "Hola, acaba de crear una nueva persona: " + nombre); }}

70

public static void main(String[] args) {

Persona ana = new Persona( "Ana", 18 );

Persona clon_de_ana = ana.clonar();

// Error, no existe el constructor:

// Persona juan = new Persona();

}

Hola, acaba de crear una nueva persona: Ana

Hola, acaba de crear una nueva persona: Ana

Ana se ha clonado a si misma/o

Page 71: Indice Introducción a Java (I). Indice Índice Tipos de datos y operadores Entradas y Salidas básicas Sentencias de control Clases 2.

Indice

Tipos de ámbito• Ya vimos que el ámbito de una variable u objeto es el espacio del programa en el

que esa variable existe. Por ello, se habla de “ámbito de vida”

• Los principales tipos de ámbitos son:– Ámbito de objeto. Los atributos de un objeto (que no son static) viven en el

espacio de vida del objeto y son accesibles por cualquier método del objeto (siempre que el método no sea static). Por ello, a veces se llaman variables de objeto o variables de instancia

– Ámbito de método. Variables y objetos declarados en un método. Su ámbito de vida se ciñe al método en el que fueron declaradas, por ello a veces se llaman variables de método o función

– Ámbito de clase. Las variables static viven con independencia de que hayamos hecho instancias de la clase. Podemos acceder a ellas (si son públicas) usando el nombre de la clase y viven desde que se declara la clase, por ello se llaman variables de clase

71

Page 72: Indice Introducción a Java (I). Indice Índice Tipos de datos y operadores Entradas y Salidas básicas Sentencias de control Clases 2.

Indice

Ambitos de objeto y de métodoEn el ejemplo de los círculos, hay variables de objeto como:

– posicion– radio

Y variables de clase (PI).También hay variables de método (locales a la función):

72

package figuras.dominio;

public class Circulo { private Punto posicion; private double radio; static final public double PI = 3.1416;

public Circulo() { } public Circulo( double nuevoRadio, Punto nuevaPosicion ) { setRadio( nuevoRadio ); setPosicion( nuevaPosicion ); } public Circulo( double nuevoRadio, int posicionX, int

posicionY ) { setRadio( nuevoRadio ); posicion = new Punto( posicionX, posicionY ); } public Circulo( Circulo circulo ) { setRadio( circulo.getRadio() ); setPosicion( circulo.getPosicion()); } public void setRadio( double radio ) { this.radio =

radio; } public void setPosicion( Punto posicion ) { this.posicion =

posicion; } public Punto getPosicion() { return posicion; } public double getRadio() { return radio; } public double getArea() { return radio *

radio * PI; } public String toString() { return "Radio: " + radio + " Posicion: " + posicion.toString() +

" Area: " + getArea(); }}

Page 73: Indice Introducción a Java (I). Indice Índice Tipos de datos y operadores Entradas y Salidas básicas Sentencias de control Clases 2.

Indice

Ámbito de clase. static• Las variables static viven con independencia de que hayamos hecho instancias de la clase• Podemos acceder a ellas (si son públicas) usando el nombre de la clase (no hay que hacer instancias)

y viven desde que se declara la clase, por ello se llaman variables de clase. Ejemplo:

• Todas las instancias de la clase comparten la misma variable static. Cosa que no ocurre con las variables no static, en estas cada objeto tiene su variable

• En el ejemplo es lógico que el atributo “PI” sea static: el número PI es único y el mismo sea cual sea el círculo

• Con los métodos static ocurre algo semejante. Son accesibles desde la clase, sin necesidad de hacer instancias. Ejemplo que convierte una cadena en un double:

String c = new String( “123.72” );double r; r = Double.parseDouble( c ); // Double es una clase, no un objeto

• Ahora podemos explicarnos por qué main debe ser static: debe ser accesible por el interprete Java antes de crear ningún objeto

• Tienen restricciones: no pueden utilizar atributos de objeto (variables no static) ni pueden llamar a métodos de objeto (métodos no static)

• Por ello un método static no puede usar la expresión “this”, ya que un método static tiene ámbito de clase y this por definición tiene ámbito de objeto 73

class Circulo {

private punto posicion;

private double radio;

static public double PI = 3.1416;

...

public static void main(String[] args) {

System.out.println( circulo.PI);

}

Page 74: Indice Introducción a Java (I). Indice Índice Tipos de datos y operadores Entradas y Salidas básicas Sentencias de control Clases 2.

Indice

final• Cuando se declara una variable como final estamos dando

la orden de que no se modifique. Es como definir una constante

• Debe ser inicializada en la declaración, ya que cualquier intento de modificarla provoca un error de compilación

• Utilidad: no permitir que un error de programación altere el valor de una constante. Ejemplo:

class circulo { private punto posicion; private double radio; static final public double PI = 3.1416;

• El uso de final en métodos tiene otro sentido: no permitir que una clase hija sobreescriba un método de la clase padre

74