SlideShare ist ein Scribd-Unternehmen logo
1 von 74
Introducción a Java (I)




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




Indice                                 2
Tipos de datos y operadores




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
                    }


Indice                                                                                                      4
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)

Indice                                                                                                      5
Los tipos de datos: enteros y coma
                                 flotantetipos de vehículos existen
         • Del mismo modo que existen diferentes
             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)



Indice                                                                                  6
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


Indice                                                                          7
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 área
                   System.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).


Indice                                                                                8
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 edad
              if (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” );


Indice                                                                                           9
•
                            Caracteres (char)16 bits. Se utiliza un
             En Java los caracteres se almacenan en variables de
             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.



Indice                                                                                   10
•
                                                     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);



Indice                                                                                               11
Á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


Indice                                                                                12
•
                        Conversión deen ocasiones nos conviene
             Hemos visto que los datos tienen un tipo. Pero
                                                            tipos
             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 );
Indice                                                                                             13
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:
                                              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
Indice                                                                                                             14
•
                                                  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] );




                                                                       Matriz

                                                    Valor:         5    9       2

Indice                                              Posición:      0    1       2
                                                                                                                15
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?

Indice                                                                                                   16
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];                                   Vehiculo.java:
                    mios[0] = new vehiculo();                package xxx;

                    mios[1] = new vehiculo();
                                                             public class Vehiculo {
                    mios[0].definir_precio_bajo();                 private int precio;
                    mios[1].definir_precio_bajo();
                    mios[1].mostrar();                             void definir_precio_bajo() {
                                                                              precio = 12000;
                  }                                                }
                                                                   void mostrar() {
                                                                              System.out.println( " Precio:" + precio);
                                                                   }
                                                             }

Indice                                                                                                                    17
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
                                                                                   200

           matrices completas resulta muy sencilla:                                400

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

Indice                                                                                   18
         •   Al intentar acceder a un elemento que está fuera del rango de la matriz se
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)
Indice     difieran. El siguiente ejemplo crea una matriz
                                                       19
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)

Indice                                                                             20
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:
Indice                                                                                  21
¿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);                  Belén es igual a Belén
               if (j.compareTo(k) < 0)                                         Belén es menor que Susana
                 System.out.println( j + " es menor que " + k);
               if (j.compareTo(n) > 0)                                         Belén es mayor que Antonio
                 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)

Indice                                                                                                  22
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)
Indice
                  System.out.println( "aprobado" );
                                                      23
             if (!mayoria_edad)
Entradas y Salidas básicas




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


               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.
Indice                                                                                            25
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




Indice                                                                                 26
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.
Indice                                                                                                                              27
Un ejemplo entrada por teclado y
                   conversión
                   public 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 casting
                       System.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.

Indice                                                                                                              28
Sentencias de control




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
Indice        – Salto                                                                    30
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) Precaución:
                                              La tabulación es
         • Ejemplo:                       fundamental para realizar
                                                  código legible
               int a = 3, b = 9, c;
Indice         if (a < b && a != 0)                                31
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;
Indice                                                                                                     32
                   }
switch
    •    Formato:
               switch ( expresión ) {                    // expresión: no tiene que ser booleano
                   case constante1:
                              secuencia de sentencias
                              break;
                   case constante2:
                              secuencia de sentencias
                              break;
                   ...
                   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:
Indice                                                                                             33
                              porcen = 0.1;
               }
•   Formato:
                                                     while
                   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];                                             Bucle
                 System.out.println( "t Cuadrado: " + serie[i] );
                 i++;
               }
                                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.0              Cuadrado: 81.0
Indice                                                                                               34
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++)
Indice                        System.out.println( i );
                                                                                                               35
for (II)
   •     Vamos a ver paso a paso como actua
                                                         1.   INICIO: la variable i se inicia a 1
         la iteración
                                                         2.   CONDICIÓN: se comprueba la
                                                              condición: ¿ i<3 ? SI
   •     Ejemplo:                                        3.   SENTENCIA: se ejecuta la sentencia
               int i;                                         println
               for ( i = 1; i < 3; i++)
                        System.out.println( i );
                                                         4.   VARIACIÓN: al terminar el bucle, se
                                                              incrementa i. Ahora vale 2
                                                         5.   CONDICIÓN: se comprueba la
   •     Al observar la ejecución paso a paso es              condición: ¿ i<3 ? SI
         importante recordar:                            6.   SENTENCIA: se ejecuta la sentencia
          – Siempre se evalúa la condición ANTES              println
            de ejecutar la sentencia                     7.   VARIACIÓN: al terminar el bucle, se
          – DESPUÉS de la sentencia siempre se                incrementa i. Ahora vale 3
            realiza la variación                         8.   CONDICIÓN: se comprueba la
                                                              condición: ¿ i<3 ? NO, fin del
   •                                                          bucle
         Se pueden iterar varias variables, para lo
         cual necesitamos comas: for(i=0, k=5; i < 5;    9.   IMPORTANTE: al salir del bucle el
         i++, k=k+5)                                          valor de i es 3. ¿Cuál sería su valor si
Indice                                                        la condición fuese i<=3?           36
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
Indice                                                                                                 37
•   Formato:
                                              do-while
                   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 teclado
                                 switch (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 calculadora
Indice                                                                                                     38
Calculadora
  public static void main(String[] args) throws IOException {                   /**** En función de la opción: opero o salgo ***/
   char opcion;                                                                 switch (opcion) {
   String cadenaTeclado;                                                          case 's':
   double operando1 = 0, operando2 = 0;                                           case 'S':
                                                                                   System.out.print( operando1 + operando2 );
   /* Creo el obj. 'entrada', es un lector de entradas por teclado */
                                                                                   break;
   BufferedReader entrada = new BufferedReader( new
                                                                                  case 'r':
       InputStreamReader(System.in));
                                                                                  case 'R':
                                                                                   System.out.print( operando1 - operando2 );
   do {                                                                            break;
    /********* Mostrar menu y pedir opcion por teclado ****/                      case 'p':
    System.out.print("rn S - Sumarn R - Restarn P - Producto" + "rn       case 'P':
      D - Divisiónrn Q - Salirrn Su opción:");                                 System.out.print( operando1 * operando2 );
    cadenaTeclado = entrada.readLine();           // Teclado                       break;
    opcion = cadenaTeclado.charAt( 0 );         // Conv a char                    case 'd':
                                                                                  case 'D':
    /********* Si la opción no es salir, solicito operandos ***/                   System.out.print( operando1 / operando2 );
    if ( opcion != 'Q' && opcion != 'q') {                                         break;
      System.out.print( "Número 1: " );                                           case 'q':
      cadenaTeclado = entrada.readLine();            // Teclado                   case 'Q':
                                                                                   System.out.print( "Adios" );
      operando1 = Double.parseDouble( cadenaTeclado ); // Conv
                                                                                   break;
      System.out.print( "Número 2: " );
                                                                                  default:
      cadenaTeclado = entrada.readLine();            // Teclado
                                                                                   System.out.print( "Opción no disponible" );
      operando2 = Double.parseDouble( cadenaTeclado ); // Conv
    }                                                                            } /////////////////////////////// Fin de switch
                                                                               } while (opcion != 'Q' && opcion != 'q');
Indice                                                                                                                           39
                                                                              } //////////////////////////////// Fin de función
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");
Indice            }                                                                                                  40
Clases




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

Indice                                                                          42
•
                                         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:

                  /******** Circulo.java ********/                                /********* Inicio.java *****/
                  package figuras.dominio;                                        package figuras.inicio;
                                                                                  import figuras.dominio.Circulo;
                  public class Circulo {
                      public double radio;                                        public class Inicio {
                      public double PI = 3.1416;                                      public static void main(String[] args) {
                  }                                                                                Circulo a; // ERROR
                                                                                                   a.radio = 23;
                                                                                      }
                                                                                  }


         •   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();
Indice                 a.radio = 23;                                                                                             43
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


Indice                                                                                     44
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) {
Indice                                               45
          Circulo a = new Circulo();
El primer método
         •   Vamos a introducir un método en nuestra clase “Circulo”, que
             simplemente muestra el área:
              public class Inicio {                          public class Circulo {
                  public static void main(String[] args) {       public double radio;
                      Circulo a = new Circulo();                 public double PI = 3.1416;
                      Circulo b = new Circulo();                 public void mostrarArea() {
                      a.radio = 23;                                  System.out.println( radio*radio*PI );
                      b.radio = 35.6;                            }
                      a.mostrarArea();                       }
                      b.mostrarArea();
                  }
              }

         •   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
Indice                                                                           46
         •   El método muestra los atributos de SU OBJETO
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

Indice                                                                               47
•
                            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




Indice                                                                                                         48
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 );
                    }                                             El parámetro “base” recibe el argumento 3
                  }
Indice                                                                                                  49
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);
              }
Indice                                                                           50
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



Indice                                                                                              51
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;

                                                                      Reglas importantes:
                          public double getArea() {
                            return radio * radio * PI;                • Encapsular: desde fuera de la clase sólo
                          }                                             se accede a los métodos públicos . No se
                          public void setRadio(double nuevoRadio) {     accede directamente a los datos
                            radio = nuevoRadio;
                                                                      • Modularizar: separar procesamiento de
                          }                                             datos de su presentación . Un ejemplo es que
                          public double getRadio() {                    los cálculos se hacen en métodos diferentes a la
                            return radio;                               presentación de datos (incluso, lo que es aún
                          }                                             mejor, en clases diferentes). También es una forma
                      }                                                 de hacer software cohesivo




Indice                                                                                                             52
•
                                   Encapsular que deben seguirse
             En la ingeniería del software se especifican reglas
             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
                                           Objeto
                                                                       Los métodos
                               Método 1                               públicos de la
                Llamada                           Datos                clase son el
                               Método 2                            interfaz de la clase
Indice                                                                             53
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()”.


Indice                                                                                         54
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.
Indice                                                                            55
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,
Indice     paquete figuras.dominio con las clases Circulo,    56
•
                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:
         package figuras.dominio;                                package figuras.presentacion;

         public class Circulo {                                  import figuras.dominio.*;
           private double radio;
           private double PI = 3.1416;                           public class VistaFiguras {

           public Circulo() { }                                      public static void mostrar( Circulo cir ) {
           public Circulo( double nuevoRadio ) {                       System.out.println( cir.toString() );
             setRadio( nuevoRadio );                                 }
           }
           public double getArea() {                                 public static void mostrar( Rectangulo rec ) {
             return radio * radio * PI;                                System.out.println( rec.toString() );
           }                                                         }
           public void setRadio( double radio ) {                }
             this.radio = radio;
           }
           public double getRadio() {                                ¿Cómo se haría un main() que use estas
             return radio;                                                          clases?
           }
           public String toString() {
             return "Radio: " + radio + " Area: " + getArea();
    Indice }                                                                                                          57
         }
•
                                         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() {                                 Circulo a = new 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 ) {                       Circulo a = new Circulo(21);
                             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)

Indice                                                                                                            58
•
                                      finalize() los objetos creados por new es
             En lenguajes como C++ la memoria ocupada por
             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


Indice                                                                                           59
Sobrecarga de métodos
         • Java nos permite tener métodos con el mismo
           nombre y que se diferencian por sus
             package figuras.presentacion;
           argumentos:                ¿Por qué hace falta hacer import de las
                                   clases del paquete “figuras.domino”? Porque
             import figuras.dominio.*;                               están en un paquete diferente que
                                                                               “VistaFiguras”
             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() );
                 }
             }


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

Indice                                                                                              60
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?
Indice                                                                                      61
El proyecto de las figuras. Los
                           puntos
         package figuras.dominio;

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

             public Punto(int x, int y) {
               setPunto(x, y);
             }
             public Punto(Punto p) {                Aspectos a resaltar:
               setPunto(p );
             }                                      • Encapsulamiento
             public void setPunto(int x, int y) {   • Sobrecarga de constructores
               this.x = x;
               this.y = y;                          • 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
             public void setPunto(Punto p) {          argumento (p)
               x = p.getX();
               y = p.getY();
             }

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

             public String toString() {
               return "(" + x + "," + y + ")";
             }
         }
Indice                                                                                                     62
El proyecto de las figuras. Los
package figuras.dominio;
                                círculos (I)                                                  Aspectos a resaltar:
                                                                                              • Encapsulamiento
public class Circulo {                                                                        • Un atributo (posicion) es un objeto de otra
  private Punto posicion;                                                                       clase (Punto)
  private double radio;
  static final public double PI = 3.1416;                                                     • PI es static (lo comentaremos más
                                                                                                adelante)
    public Circulo() { }                                                                       •   PI es final: es una constante, no puede
    public Circulo( double nuevoRadio, Punto nuevaPosicion ) {                                     cambiarse. Esto evita modificaciones
       setRadio( nuevoRadio );                                                                     accidentales por parte del programador
       setPosicion( nuevaPosicion );
    }
                                                                                               •   Sobrecarga de constructores
    public Circulo( double nuevoRadio, int posicionX, int posicionY ) {                        •   Constructor “de copia”: Circulo(Circulo
       setRadio( nuevoRadio );                                                                     circulo). Con este constructor se hace un
       posicion = new Punto( posicionX, posicionY );                                               círculo que es una copia del objeto que se
    }                                                                                              pasa como argumento (circulo)
    public Circulo( Circulo circulo ) {                                                        •   ¿Por qué no hace falta import de la clase
       setRadio( circulo.getRadio() );                                                             “Punto”? Porque está en el mismo paquete
       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();
    }
      Indice                                                                                                                          63
}
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.

Indice                                                                               64
El proyecto de las figuras. La
                           visualización
         package figuras.presentacion;
                                                              Aspectos a resaltar:
         import figuras.dominio.*;                            • Modularidad: separamos la presentación
                                                                (“VistaFiguras”) de las clases de dominio
         public class VistaFiguras {                            de problema (puntos, círculos, etc.)
                                                              • Sobrecarga de constructores
             public static void mostrar( Circulo cir ) {
                                                              • ¿Por qué hace falta import de las clases
               System.out.println( cir.toString() );            del paquete “figuras.dominio”? Porque
             }                                                  dichas clases están en un paquete
                                                                diferente al de “VistaFiguras”
             public static void mostrar( Rectangulo rec ) {
               System.out.println( rec.toString() );
             }
         }




Indice                                                                                               65
El proyecto de las figuras. El inicio
         package figuras.inicio;                                 Aspectos a resaltar:
         import figuras.dominio.*;                               • Sobrecarga de constructores
         import figuras.presentacion.*;                          • Usamos constructor de copia
                                                                 • ¿Por qué hacen falta imports?
         class Inicio {
                                                                   • Si hubiera que hacer la clase
            public static void main(String[] args) {                 Rectangulo, ¿cómo sería?
              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 );
             }
         }




Indice                                                                                               66
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 );                                         Copia del valor: 11.5
                     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”.
Indice                                                                                              67
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”)




Indice                                                                                    68
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 );
         }


Indice   public static void cambiarDespedida( String mensaje ) {                           69
            mensaje = "Hasta luego";
Devolución de objetos
    Hemos 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 {                                                  public static void main(String[] args) {
        private String nombre;                                                   Persona ana = new Persona( "Ana", 18 );
        private int edad;
                                                                                 Persona clon_de_ana = ana.clonar();
        public Persona( String nuevoNombre, int nuevaEdad ) {
                                                                                // Error, no existe el constructor:
          setPersona( nuevoNombre, nuevaEdad );
          mostrarSaludo();                                                      // Persona juan = new Persona();
        }                                                                     }
        public void setPersona( String nuevoNombre, int nuevaEdad ) {
          nombre = nuevoNombre;
          edad = nuevaEdad;                                                  Hola, acaba de crear una nueva persona: Ana
        }
                                                                             Hola, acaba de crear una nueva persona: Ana
        public persona clonar( ) {
                                                                             Ana se ha clonado a si misma/o
          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);
        }
      }
Indice                                                                                                                 70
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



Indice                                                                                     71
Ambitos de objeto y de método
                                 package figuras.dominio;
En el ejemplo de los círculos,   public class Circulo {
hay variables de objeto como:      private Punto posicion;
                                   private double radio;
         – posicion                static final public double PI = 3.1416;
         – radio
                                     public Circulo() { }
Y variables de clase (PI).           public Circulo( double nuevoRadio, Punto nuevaPosicion ) {
                                       setRadio( nuevoRadio );
También hay variables de               setPosicion( nuevaPosicion );
método (locales a la función):       }
                                     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();
                                     }
Indice                                                                                                         72
                                 }
Á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:

                   class Circulo {                                          public static void main(String[] args) {
                     private punto posicion;                                     System.out.println( circulo.PI);
                     private double radio;                                  }
                     static public double PI = 3.1416;
                   ...
•    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)
 •
Indice 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
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 {
Indice    private punto posicion;                   74

Weitere ähnliche Inhalte

Was ist angesagt?

Punteros y elementos dinámicos en c++
Punteros y elementos dinámicos en c++Punteros y elementos dinámicos en c++
Punteros y elementos dinámicos en c++Tensor
 
Taller de lenguaje 1
Taller de lenguaje 1Taller de lenguaje 1
Taller de lenguaje 1Yesenia Gomez
 
Mynor Alexander Hernandez Canuz
Mynor Alexander Hernandez CanuzMynor Alexander Hernandez Canuz
Mynor Alexander Hernandez Canuzguest79d55c9
 
Manualito C/C++ - Leonardo Aquino
Manualito C/C++ - Leonardo AquinoManualito C/C++ - Leonardo Aquino
Manualito C/C++ - Leonardo AquinoEstudiantes ISI_UCA
 
Cadena de caracteres
Cadena de caracteresCadena de caracteres
Cadena de caractereszerorendan
 
Lenguaje C para Administradores de Red - Script II Punteros
Lenguaje C para Administradores de Red - Script II PunterosLenguaje C para Administradores de Red - Script II Punteros
Lenguaje C para Administradores de Red - Script II Punterossirfids
 
Tema 2 tipos de datos y expresiones en java por gio
Tema 2   tipos de datos y expresiones en java por gioTema 2   tipos de datos y expresiones en java por gio
Tema 2 tipos de datos y expresiones en java por gioRobert Wolf
 
07 - Tipos de datos definidos por el programador en lenguaje C: struct, typed...
07 - Tipos de datos definidos por el programador en lenguaje C: struct, typed...07 - Tipos de datos definidos por el programador en lenguaje C: struct, typed...
07 - Tipos de datos definidos por el programador en lenguaje C: struct, typed...Diego Andrés Alvarez Marín
 
Elementos del lenguaje variables y estructuras de datos
Elementos del lenguaje variables y estructuras de datosElementos del lenguaje variables y estructuras de datos
Elementos del lenguaje variables y estructuras de datosjnarchie
 
Prog manejo de variables
Prog manejo de variablesProg manejo de variables
Prog manejo de variablesAdriana Vega P
 

Was ist angesagt? (19)

Punteros y elementos dinámicos en c++
Punteros y elementos dinámicos en c++Punteros y elementos dinámicos en c++
Punteros y elementos dinámicos en c++
 
Java001
Java001Java001
Java001
 
Taller
TallerTaller
Taller
 
Taller de lenguaje 1
Taller de lenguaje 1Taller de lenguaje 1
Taller de lenguaje 1
 
Mynor Alexander Hernandez Canuz
Mynor Alexander Hernandez CanuzMynor Alexander Hernandez Canuz
Mynor Alexander Hernandez Canuz
 
Clase1
Clase1Clase1
Clase1
 
Manualito C/C++ - Leonardo Aquino
Manualito C/C++ - Leonardo AquinoManualito C/C++ - Leonardo Aquino
Manualito C/C++ - Leonardo Aquino
 
Cadena de caracteres
Cadena de caracteresCadena de caracteres
Cadena de caracteres
 
Lenguaje C para Administradores de Red - Script II Punteros
Lenguaje C para Administradores de Red - Script II PunterosLenguaje C para Administradores de Red - Script II Punteros
Lenguaje C para Administradores de Red - Script II Punteros
 
Material iii parcial
Material iii parcialMaterial iii parcial
Material iii parcial
 
Tipos de datos Java
Tipos de datos JavaTipos de datos Java
Tipos de datos Java
 
Cap I
Cap ICap I
Cap I
 
Tema 2 tipos de datos y expresiones en java por gio
Tema 2   tipos de datos y expresiones en java por gioTema 2   tipos de datos y expresiones en java por gio
Tema 2 tipos de datos y expresiones en java por gio
 
Aejemplosc
AejemploscAejemplosc
Aejemplosc
 
07 - Tipos de datos definidos por el programador en lenguaje C: struct, typed...
07 - Tipos de datos definidos por el programador en lenguaje C: struct, typed...07 - Tipos de datos definidos por el programador en lenguaje C: struct, typed...
07 - Tipos de datos definidos por el programador en lenguaje C: struct, typed...
 
Elementos del lenguaje variables y estructuras de datos
Elementos del lenguaje variables y estructuras de datosElementos del lenguaje variables y estructuras de datos
Elementos del lenguaje variables y estructuras de datos
 
08 - Punteros en lenguaje C
08 - Punteros en lenguaje C08 - Punteros en lenguaje C
08 - Punteros en lenguaje C
 
Mod2ud1 2
Mod2ud1 2Mod2ud1 2
Mod2ud1 2
 
Prog manejo de variables
Prog manejo de variablesProg manejo de variables
Prog manejo de variables
 

Ähnlich wie Presentacion 4 (20)

02 - Conceptos fundamentales sobre tipos de datos en lenguaje C
02 - Conceptos fundamentales sobre tipos de datos en lenguaje C02 - Conceptos fundamentales sobre tipos de datos en lenguaje C
02 - Conceptos fundamentales sobre tipos de datos en lenguaje C
 
LibreríAs De Java
LibreríAs De JavaLibreríAs De Java
LibreríAs De Java
 
P-S2.pptx
P-S2.pptxP-S2.pptx
P-S2.pptx
 
Introduccion al lenguaje c
Introduccion al lenguaje cIntroduccion al lenguaje c
Introduccion al lenguaje c
 
Investigacion 1
Investigacion 1Investigacion 1
Investigacion 1
 
Manual de c c++
Manual de c c++Manual de c c++
Manual de c c++
 
02 - Tipos de datos escalares en Python 3
02 - Tipos de datos escalares en Python 302 - Tipos de datos escalares en Python 3
02 - Tipos de datos escalares en Python 3
 
Curso c++
Curso c++Curso c++
Curso c++
 
Tipos de datos primitivos en c++
Tipos de datos primitivos en c++Tipos de datos primitivos en c++
Tipos de datos primitivos en c++
 
tutorial de c++
tutorial de c++tutorial de c++
tutorial de c++
 
Tutorial C++
Tutorial C++Tutorial C++
Tutorial C++
 
2 punteros y lenguaje c
2 punteros y lenguaje c2 punteros y lenguaje c
2 punteros y lenguaje c
 
Java Basico Platzi
Java Basico PlatziJava Basico Platzi
Java Basico Platzi
 
Programar java
Programar javaProgramar java
Programar java
 
Tipos de datos
Tipos de datosTipos de datos
Tipos de datos
 
4 variables, arreglos, estructuras y enum
4 variables, arreglos, estructuras y enum4 variables, arreglos, estructuras y enum
4 variables, arreglos, estructuras y enum
 
Diapositivas curso programación orientada a objetos en Java
Diapositivas curso programación orientada a objetos en JavaDiapositivas curso programación orientada a objetos en Java
Diapositivas curso programación orientada a objetos en Java
 
Desarrollo desoftware
Desarrollo desoftwareDesarrollo desoftware
Desarrollo desoftware
 
JAVA
JAVAJAVA
JAVA
 
Tipos de datos ok
Tipos de datos okTipos de datos ok
Tipos de datos ok
 

Mehr von ayreonmx

Presentation1
Presentation1Presentation1
Presentation1ayreonmx
 
Sistemas distribuidos
Sistemas distribuidosSistemas distribuidos
Sistemas distribuidosayreonmx
 
Clase 6 sistemas raid
Clase 6   sistemas raidClase 6   sistemas raid
Clase 6 sistemas raidayreonmx
 
Sistemas operativos procesos
Sistemas operativos   procesosSistemas operativos   procesos
Sistemas operativos procesosayreonmx
 
Tratamiento de seguridad en aplicaciones
Tratamiento de seguridad en aplicacionesTratamiento de seguridad en aplicaciones
Tratamiento de seguridad en aplicacionesayreonmx
 
Maquinas virtuales
Maquinas virtualesMaquinas virtuales
Maquinas virtualesayreonmx
 
Presentacion 3
Presentacion 3Presentacion 3
Presentacion 3ayreonmx
 
1 fundamentos java
1 fundamentos java1 fundamentos java
1 fundamentos javaayreonmx
 
Introduccion poo2
Introduccion poo2Introduccion poo2
Introduccion poo2ayreonmx
 
Intro to the arduino
Intro to the arduinoIntro to the arduino
Intro to the arduinoayreonmx
 
Introducción a los microprocesadores vi
Introducción a los microprocesadores viIntroducción a los microprocesadores vi
Introducción a los microprocesadores viayreonmx
 
Programacion de microcontroladores
Programacion de microcontroladoresProgramacion de microcontroladores
Programacion de microcontroladoresayreonmx
 
Presentacion3
Presentacion3Presentacion3
Presentacion3ayreonmx
 
Presentacion2
Presentacion2Presentacion2
Presentacion2ayreonmx
 
Manual del proteus
Manual del proteusManual del proteus
Manual del proteusayreonmx
 
Java – ejercicio 3
Java – ejercicio 3Java – ejercicio 3
Java – ejercicio 3ayreonmx
 
Java – ejercicio 2
Java – ejercicio 2Java – ejercicio 2
Java – ejercicio 2ayreonmx
 
Java ejercicio 1
Java   ejercicio 1Java   ejercicio 1
Java ejercicio 1ayreonmx
 

Mehr von ayreonmx (20)

Raid
RaidRaid
Raid
 
Presentation1
Presentation1Presentation1
Presentation1
 
Sistemas distribuidos
Sistemas distribuidosSistemas distribuidos
Sistemas distribuidos
 
Clase 6 sistemas raid
Clase 6   sistemas raidClase 6   sistemas raid
Clase 6 sistemas raid
 
Sistemas operativos procesos
Sistemas operativos   procesosSistemas operativos   procesos
Sistemas operativos procesos
 
Tratamiento de seguridad en aplicaciones
Tratamiento de seguridad en aplicacionesTratamiento de seguridad en aplicaciones
Tratamiento de seguridad en aplicaciones
 
Maquinas virtuales
Maquinas virtualesMaquinas virtuales
Maquinas virtuales
 
Presentacion 3
Presentacion 3Presentacion 3
Presentacion 3
 
1 fundamentos java
1 fundamentos java1 fundamentos java
1 fundamentos java
 
Introduccion poo2
Introduccion poo2Introduccion poo2
Introduccion poo2
 
Intro to the arduino
Intro to the arduinoIntro to the arduino
Intro to the arduino
 
Introducción a los microprocesadores vi
Introducción a los microprocesadores viIntroducción a los microprocesadores vi
Introducción a los microprocesadores vi
 
Programacion de microcontroladores
Programacion de microcontroladoresProgramacion de microcontroladores
Programacion de microcontroladores
 
Presentacion3
Presentacion3Presentacion3
Presentacion3
 
Presentacion2
Presentacion2Presentacion2
Presentacion2
 
Cli unix2
Cli unix2Cli unix2
Cli unix2
 
Manual del proteus
Manual del proteusManual del proteus
Manual del proteus
 
Java – ejercicio 3
Java – ejercicio 3Java – ejercicio 3
Java – ejercicio 3
 
Java – ejercicio 2
Java – ejercicio 2Java – ejercicio 2
Java – ejercicio 2
 
Java ejercicio 1
Java   ejercicio 1Java   ejercicio 1
Java ejercicio 1
 

Kürzlich hochgeladen

Supremacia de la Constitucion 2024.pptxm
Supremacia de la Constitucion 2024.pptxmSupremacia de la Constitucion 2024.pptxm
Supremacia de la Constitucion 2024.pptxmolivayasser2
 
Geometría para alumnos de segundo medio A
Geometría para alumnos de segundo medio AGeometría para alumnos de segundo medio A
Geometría para alumnos de segundo medio APabloBascur3
 
como me enamore de ti (1).pdf.pdf_20240401_120711_0000.pdf
como me enamore de ti (1).pdf.pdf_20240401_120711_0000.pdfcomo me enamore de ti (1).pdf.pdf_20240401_120711_0000.pdf
como me enamore de ti (1).pdf.pdf_20240401_120711_0000.pdfleonar947720602
 
la configuyracion del territorio peruano
la configuyracion del territorio peruanola configuyracion del territorio peruano
la configuyracion del territorio peruanoEFRAINSALAZARLOYOLA1
 
Arribando a la concreción II. Títulos en inglés, alemán y español
Arribando a la concreción II. Títulos en inglés, alemán y españolArribando a la concreción II. Títulos en inglés, alemán y español
Arribando a la concreción II. Títulos en inglés, alemán y españolLuis José Ferreira Calvo
 
26 de abril teoria exposición. El arte en la
26 de abril teoria exposición. El arte en la26 de abril teoria exposición. El arte en la
26 de abril teoria exposición. El arte en laMIRIANGRACIELABARBOZ
 
SEMIOLOGIA DE CABEZA Y CUELLO. Medicina Semiologia cabeza y cuellopptx
SEMIOLOGIA DE CABEZA Y CUELLO. Medicina Semiologia cabeza y cuellopptxSEMIOLOGIA DE CABEZA Y CUELLO. Medicina Semiologia cabeza y cuellopptx
SEMIOLOGIA DE CABEZA Y CUELLO. Medicina Semiologia cabeza y cuellopptxLisetteChuquisea
 
MESOPOTAMIA Y SU ARQUITECTURA 1006/An)cris
MESOPOTAMIA Y SU ARQUITECTURA 1006/An)crisMESOPOTAMIA Y SU ARQUITECTURA 1006/An)cris
MESOPOTAMIA Y SU ARQUITECTURA 1006/An)crisDanielApalaBello
 
GEODESIA pptx.pdfhhjjgjkhkjhgyfturtuuuhhuh
GEODESIA pptx.pdfhhjjgjkhkjhgyfturtuuuhhuhGEODESIA pptx.pdfhhjjgjkhkjhgyfturtuuuhhuh
GEODESIA pptx.pdfhhjjgjkhkjhgyfturtuuuhhuhmezabellosaidjhon
 
MODELO DE UNIDAD 2 para primer grado de primaria
MODELO DE UNIDAD 2 para primer grado de primariaMODELO DE UNIDAD 2 para primer grado de primaria
MODELO DE UNIDAD 2 para primer grado de primariaSilvanaSoto13
 
diagrama sinóptico dcerfghjsxdcfvgbhnjdcf
diagrama sinóptico dcerfghjsxdcfvgbhnjdcfdiagrama sinóptico dcerfghjsxdcfvgbhnjdcf
diagrama sinóptico dcerfghjsxdcfvgbhnjdcfDreydyAvila
 
CERTIFICADO para NIÑOS, presentacion de niños en la iglesia .pptx
CERTIFICADO para NIÑOS, presentacion de niños en la iglesia .pptxCERTIFICADO para NIÑOS, presentacion de niños en la iglesia .pptx
CERTIFICADO para NIÑOS, presentacion de niños en la iglesia .pptxMaikelPereira1
 
ACUERDOS PARA PINTAR EDUCACION INICIAL.docx
ACUERDOS PARA PINTAR EDUCACION INICIAL.docxACUERDOS PARA PINTAR EDUCACION INICIAL.docx
ACUERDOS PARA PINTAR EDUCACION INICIAL.docxlizeth753950
 
Unitario - Serie Fotográfica - Emmanuel Toloza Pineda
Unitario - Serie Fotográfica - Emmanuel Toloza PinedaUnitario - Serie Fotográfica - Emmanuel Toloza Pineda
Unitario - Serie Fotográfica - Emmanuel Toloza PinedaEmmanuel Toloza
 
Concepto de Estética, aproximación,Elena Olvieras
Concepto de Estética, aproximación,Elena OlvierasConcepto de Estética, aproximación,Elena Olvieras
Concepto de Estética, aproximación,Elena OlvierasAnkara2
 
LAVADO DE MANOS TRIPTICO modelos de.docx
LAVADO DE MANOS TRIPTICO modelos de.docxLAVADO DE MANOS TRIPTICO modelos de.docx
LAVADO DE MANOS TRIPTICO modelos de.docxJheissonAriasSalazar
 
PROCESO ADMINISTRATIVO Proceso administrativo de enfermería desde sus bases, ...
PROCESO ADMINISTRATIVO Proceso administrativo de enfermería desde sus bases, ...PROCESO ADMINISTRATIVO Proceso administrativo de enfermería desde sus bases, ...
PROCESO ADMINISTRATIVO Proceso administrativo de enfermería desde sus bases, ...albertodeleon1786
 
Origen del Hombre- cuadro comparativo 5to Sec
Origen del Hombre- cuadro comparativo 5to SecOrigen del Hombre- cuadro comparativo 5to Sec
Origen del Hombre- cuadro comparativo 5to Secssuser50da781
 
presentacion-auditoria-administrativa-i-encuentro (1).ppt
presentacion-auditoria-administrativa-i-encuentro (1).pptpresentacion-auditoria-administrativa-i-encuentro (1).ppt
presentacion-auditoria-administrativa-i-encuentro (1).pptDerekLiberatoMartine
 
271706433-Horacio-Baliero-Casa-en-Punta-Piedras.pptx
271706433-Horacio-Baliero-Casa-en-Punta-Piedras.pptx271706433-Horacio-Baliero-Casa-en-Punta-Piedras.pptx
271706433-Horacio-Baliero-Casa-en-Punta-Piedras.pptxjezuz1231
 

Kürzlich hochgeladen (20)

Supremacia de la Constitucion 2024.pptxm
Supremacia de la Constitucion 2024.pptxmSupremacia de la Constitucion 2024.pptxm
Supremacia de la Constitucion 2024.pptxm
 
Geometría para alumnos de segundo medio A
Geometría para alumnos de segundo medio AGeometría para alumnos de segundo medio A
Geometría para alumnos de segundo medio A
 
como me enamore de ti (1).pdf.pdf_20240401_120711_0000.pdf
como me enamore de ti (1).pdf.pdf_20240401_120711_0000.pdfcomo me enamore de ti (1).pdf.pdf_20240401_120711_0000.pdf
como me enamore de ti (1).pdf.pdf_20240401_120711_0000.pdf
 
la configuyracion del territorio peruano
la configuyracion del territorio peruanola configuyracion del territorio peruano
la configuyracion del territorio peruano
 
Arribando a la concreción II. Títulos en inglés, alemán y español
Arribando a la concreción II. Títulos en inglés, alemán y españolArribando a la concreción II. Títulos en inglés, alemán y español
Arribando a la concreción II. Títulos en inglés, alemán y español
 
26 de abril teoria exposición. El arte en la
26 de abril teoria exposición. El arte en la26 de abril teoria exposición. El arte en la
26 de abril teoria exposición. El arte en la
 
SEMIOLOGIA DE CABEZA Y CUELLO. Medicina Semiologia cabeza y cuellopptx
SEMIOLOGIA DE CABEZA Y CUELLO. Medicina Semiologia cabeza y cuellopptxSEMIOLOGIA DE CABEZA Y CUELLO. Medicina Semiologia cabeza y cuellopptx
SEMIOLOGIA DE CABEZA Y CUELLO. Medicina Semiologia cabeza y cuellopptx
 
MESOPOTAMIA Y SU ARQUITECTURA 1006/An)cris
MESOPOTAMIA Y SU ARQUITECTURA 1006/An)crisMESOPOTAMIA Y SU ARQUITECTURA 1006/An)cris
MESOPOTAMIA Y SU ARQUITECTURA 1006/An)cris
 
GEODESIA pptx.pdfhhjjgjkhkjhgyfturtuuuhhuh
GEODESIA pptx.pdfhhjjgjkhkjhgyfturtuuuhhuhGEODESIA pptx.pdfhhjjgjkhkjhgyfturtuuuhhuh
GEODESIA pptx.pdfhhjjgjkhkjhgyfturtuuuhhuh
 
MODELO DE UNIDAD 2 para primer grado de primaria
MODELO DE UNIDAD 2 para primer grado de primariaMODELO DE UNIDAD 2 para primer grado de primaria
MODELO DE UNIDAD 2 para primer grado de primaria
 
diagrama sinóptico dcerfghjsxdcfvgbhnjdcf
diagrama sinóptico dcerfghjsxdcfvgbhnjdcfdiagrama sinóptico dcerfghjsxdcfvgbhnjdcf
diagrama sinóptico dcerfghjsxdcfvgbhnjdcf
 
CERTIFICADO para NIÑOS, presentacion de niños en la iglesia .pptx
CERTIFICADO para NIÑOS, presentacion de niños en la iglesia .pptxCERTIFICADO para NIÑOS, presentacion de niños en la iglesia .pptx
CERTIFICADO para NIÑOS, presentacion de niños en la iglesia .pptx
 
ACUERDOS PARA PINTAR EDUCACION INICIAL.docx
ACUERDOS PARA PINTAR EDUCACION INICIAL.docxACUERDOS PARA PINTAR EDUCACION INICIAL.docx
ACUERDOS PARA PINTAR EDUCACION INICIAL.docx
 
Unitario - Serie Fotográfica - Emmanuel Toloza Pineda
Unitario - Serie Fotográfica - Emmanuel Toloza PinedaUnitario - Serie Fotográfica - Emmanuel Toloza Pineda
Unitario - Serie Fotográfica - Emmanuel Toloza Pineda
 
Concepto de Estética, aproximación,Elena Olvieras
Concepto de Estética, aproximación,Elena OlvierasConcepto de Estética, aproximación,Elena Olvieras
Concepto de Estética, aproximación,Elena Olvieras
 
LAVADO DE MANOS TRIPTICO modelos de.docx
LAVADO DE MANOS TRIPTICO modelos de.docxLAVADO DE MANOS TRIPTICO modelos de.docx
LAVADO DE MANOS TRIPTICO modelos de.docx
 
PROCESO ADMINISTRATIVO Proceso administrativo de enfermería desde sus bases, ...
PROCESO ADMINISTRATIVO Proceso administrativo de enfermería desde sus bases, ...PROCESO ADMINISTRATIVO Proceso administrativo de enfermería desde sus bases, ...
PROCESO ADMINISTRATIVO Proceso administrativo de enfermería desde sus bases, ...
 
Origen del Hombre- cuadro comparativo 5to Sec
Origen del Hombre- cuadro comparativo 5to SecOrigen del Hombre- cuadro comparativo 5to Sec
Origen del Hombre- cuadro comparativo 5to Sec
 
presentacion-auditoria-administrativa-i-encuentro (1).ppt
presentacion-auditoria-administrativa-i-encuentro (1).pptpresentacion-auditoria-administrativa-i-encuentro (1).ppt
presentacion-auditoria-administrativa-i-encuentro (1).ppt
 
271706433-Horacio-Baliero-Casa-en-Punta-Piedras.pptx
271706433-Horacio-Baliero-Casa-en-Punta-Piedras.pptx271706433-Horacio-Baliero-Casa-en-Punta-Piedras.pptx
271706433-Horacio-Baliero-Casa-en-Punta-Piedras.pptx
 

Presentacion 4

  • 1. Introducción a Java (I) Indice
  • 2. Índice • Tipos de datos y operadores • Entradas y Salidas básicas • Sentencias de control • Clases Indice 2
  • 3. Tipos de datos y operadores Indice
  • 4. 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 } Indice 4
  • 5. 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) Indice 5
  • 6. Los tipos de datos: enteros y coma flotantetipos de vehículos existen • Del mismo modo que existen diferentes 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) Indice 6
  • 7. 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 Indice 7
  • 8. 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 área System.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). Indice 8
  • 9. 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 edad if (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” ); Indice 9
  • 10. Caracteres (char)16 bits. Se utiliza un En Java los caracteres se almacenan en variables de 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. Indice 10
  • 11. 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); Indice 11
  • 12. Á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 Indice 12
  • 13. Conversión deen ocasiones nos conviene Hemos visto que los datos tienen un tipo. Pero tipos 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 ); Indice 13
  • 14. 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: 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 Indice 14
  • 15. 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] ); Matriz Valor: 5 9 2 Indice Posición: 0 1 2 15
  • 16. 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? Indice 16
  • 17. 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]; Vehiculo.java: mios[0] = new vehiculo(); package xxx; mios[1] = new vehiculo(); public class Vehiculo { mios[0].definir_precio_bajo(); private int precio; mios[1].definir_precio_bajo(); mios[1].mostrar(); void definir_precio_bajo() { precio = 12000; } } void mostrar() { System.out.println( " Precio:" + precio); } } Indice 17
  • 18. 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 200 matrices completas resulta muy sencilla: 400 int Origen[] = { 200, 400, 600 }; int Destino[] = { 10, 20, 30 }; Destino = Origen; System.out.println( Destino[0] ); System.out.println( Destino[1] ); Indice 18 • Al intentar acceder a un elemento que está fuera del rango de la matriz se
  • 19. 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) Indice difieran. El siguiente ejemplo crea una matriz 19
  • 20. 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) Indice 20
  • 21. 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: Indice 21
  • 22. ¿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); Belén es igual a Belén if (j.compareTo(k) < 0) Belén es menor que Susana System.out.println( j + " es menor que " + k); if (j.compareTo(n) > 0) Belén es mayor que Antonio 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) Indice 22
  • 23. 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) Indice System.out.println( "aprobado" ); 23 if (!mayoria_edad)
  • 24. Entradas y Salidas básicas Indice
  • 25. 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 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. Indice 25
  • 26. 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 Indice 26
  • 27. 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. Indice 27
  • 28. Un ejemplo entrada por teclado y conversión public 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 casting System.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. Indice 28
  • 30. 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 Indice – Salto 30
  • 31. 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) Precaución: La tabulación es • Ejemplo: fundamental para realizar código legible int a = 3, b = 9, c; Indice if (a < b && a != 0) 31
  • 32. 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; Indice 32 }
  • 33. switch • Formato: switch ( expresión ) { // expresión: no tiene que ser booleano case constante1: secuencia de sentencias break; case constante2: secuencia de sentencias break; ... 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: Indice 33 porcen = 0.1; }
  • 34. Formato: while 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]; Bucle System.out.println( "t Cuadrado: " + serie[i] ); i++; } 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.0 Cuadrado: 81.0 Indice 34
  • 35. 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++) Indice System.out.println( i ); 35
  • 36. for (II) • Vamos a ver paso a paso como actua 1. INICIO: la variable i se inicia a 1 la iteración 2. CONDICIÓN: se comprueba la condición: ¿ i<3 ? SI • Ejemplo: 3. SENTENCIA: se ejecuta la sentencia int i; println for ( i = 1; i < 3; i++) System.out.println( i ); 4. VARIACIÓN: al terminar el bucle, se incrementa i. Ahora vale 2 5. CONDICIÓN: se comprueba la • Al observar la ejecución paso a paso es condición: ¿ i<3 ? SI importante recordar: 6. SENTENCIA: se ejecuta la sentencia – Siempre se evalúa la condición ANTES println de ejecutar la sentencia 7. VARIACIÓN: al terminar el bucle, se – DESPUÉS de la sentencia siempre se incrementa i. Ahora vale 3 realiza la variación 8. CONDICIÓN: se comprueba la condición: ¿ i<3 ? NO, fin del • bucle Se pueden iterar varias variables, para lo cual necesitamos comas: for(i=0, k=5; i < 5; 9. IMPORTANTE: al salir del bucle el i++, k=k+5) valor de i es 3. ¿Cuál sería su valor si Indice la condición fuese i<=3? 36
  • 37. 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 Indice 37
  • 38. Formato: do-while 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 teclado switch (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 calculadora Indice 38
  • 39. Calculadora public static void main(String[] args) throws IOException { /**** En función de la opción: opero o salgo ***/ char opcion; switch (opcion) { String cadenaTeclado; case 's': double operando1 = 0, operando2 = 0; case 'S': System.out.print( operando1 + operando2 ); /* Creo el obj. 'entrada', es un lector de entradas por teclado */ break; BufferedReader entrada = new BufferedReader( new case 'r': InputStreamReader(System.in)); case 'R': System.out.print( operando1 - operando2 ); do { break; /********* Mostrar menu y pedir opcion por teclado ****/ case 'p': System.out.print("rn S - Sumarn R - Restarn P - Producto" + "rn case 'P': D - Divisiónrn Q - Salirrn Su opción:"); System.out.print( operando1 * operando2 ); cadenaTeclado = entrada.readLine(); // Teclado break; opcion = cadenaTeclado.charAt( 0 ); // Conv a char case 'd': case 'D': /********* Si la opción no es salir, solicito operandos ***/ System.out.print( operando1 / operando2 ); if ( opcion != 'Q' && opcion != 'q') { break; System.out.print( "Número 1: " ); case 'q': cadenaTeclado = entrada.readLine(); // Teclado case 'Q': System.out.print( "Adios" ); operando1 = Double.parseDouble( cadenaTeclado ); // Conv break; System.out.print( "Número 2: " ); default: cadenaTeclado = entrada.readLine(); // Teclado System.out.print( "Opción no disponible" ); operando2 = Double.parseDouble( cadenaTeclado ); // Conv } } /////////////////////////////// Fin de switch } while (opcion != 'Q' && opcion != 'q'); Indice 39 } //////////////////////////////// Fin de función
  • 40. 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"); Indice } 40
  • 42. 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 Indice 42
  • 43. 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: /******** Circulo.java ********/ /********* Inicio.java *****/ package figuras.dominio; package figuras.inicio; import figuras.dominio.Circulo; public class Circulo { public double radio; public class Inicio { public double PI = 3.1416; public static void main(String[] args) { } Circulo a; // ERROR a.radio = 23; } } • 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(); Indice a.radio = 23; 43
  • 44. 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 Indice 44
  • 45. 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) { Indice 45 Circulo a = new Circulo();
  • 46. El primer método • Vamos a introducir un método en nuestra clase “Circulo”, que simplemente muestra el área: public class Inicio { public class Circulo { public static void main(String[] args) { public double radio; Circulo a = new Circulo(); public double PI = 3.1416; Circulo b = new Circulo(); public void mostrarArea() { a.radio = 23; System.out.println( radio*radio*PI ); b.radio = 35.6; } a.mostrarArea(); } b.mostrarArea(); } } • 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 Indice 46 • El método muestra los atributos de SU OBJETO
  • 47. 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 Indice 47
  • 48. 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 Indice 48
  • 49. 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 ); } El parámetro “base” recibe el argumento 3 } Indice 49
  • 50. 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); } Indice 50
  • 51. 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 Indice 51
  • 52. 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; Reglas importantes: public double getArea() { return radio * radio * PI; • Encapsular: desde fuera de la clase sólo } se accede a los métodos públicos . No se public void setRadio(double nuevoRadio) { accede directamente a los datos radio = nuevoRadio; • Modularizar: separar procesamiento de } datos de su presentación . Un ejemplo es que public double getRadio() { los cálculos se hacen en métodos diferentes a la return radio; presentación de datos (incluso, lo que es aún } mejor, en clases diferentes). También es una forma } de hacer software cohesivo Indice 52
  • 53. Encapsular que deben seguirse En la ingeniería del software se especifican reglas 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 Objeto Los métodos Método 1 públicos de la Llamada Datos clase son el Método 2 interfaz de la clase Indice 53
  • 54. 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()”. Indice 54
  • 55. 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. Indice 55
  • 56. 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, Indice paquete figuras.dominio con las clases Circulo, 56
  • 57. 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: package figuras.dominio; package figuras.presentacion; public class Circulo { import figuras.dominio.*; private double radio; private double PI = 3.1416; public class VistaFiguras { public Circulo() { } public static void mostrar( Circulo cir ) { public Circulo( double nuevoRadio ) { System.out.println( cir.toString() ); setRadio( nuevoRadio ); } } public double getArea() { public static void mostrar( Rectangulo rec ) { return radio * radio * PI; System.out.println( rec.toString() ); } } public void setRadio( double radio ) { } this.radio = radio; } public double getRadio() { ¿Cómo se haría un main() que use estas return radio; clases? } public String toString() { return "Radio: " + radio + " Area: " + getArea(); Indice } 57 }
  • 58. 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() { Circulo a = new 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 ) { Circulo a = new Circulo(21); 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) Indice 58
  • 59. finalize() los objetos creados por new es En lenguajes como C++ la memoria ocupada por 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 Indice 59
  • 60. Sobrecarga de métodos • Java nos permite tener métodos con el mismo nombre y que se diferencian por sus package figuras.presentacion; argumentos: ¿Por qué hace falta hacer import de las clases del paquete “figuras.domino”? Porque import figuras.dominio.*; están en un paquete diferente que “VistaFiguras” 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() ); } } Al llamar a un método, Java busca la versión del método que coincide con los argumentos de la llamada Indice 60
  • 61. 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? Indice 61
  • 62. El proyecto de las figuras. Los puntos package figuras.dominio; public class Punto { private int x; private int y; public Punto(int x, int y) { setPunto(x, y); } public Punto(Punto p) { Aspectos a resaltar: setPunto(p ); } • Encapsulamiento public void setPunto(int x, int y) { • Sobrecarga de constructores this.x = x; this.y = y; • 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 public void setPunto(Punto p) { argumento (p) x = p.getX(); y = p.getY(); } public int getX() { return x; } public int getY() { return y; } public String toString() { return "(" + x + "," + y + ")"; } } Indice 62
  • 63. El proyecto de las figuras. Los package figuras.dominio; círculos (I) Aspectos a resaltar: • Encapsulamiento public class Circulo { • Un atributo (posicion) es un objeto de otra private Punto posicion; clase (Punto) private double radio; static final public double PI = 3.1416; • PI es static (lo comentaremos más adelante) public Circulo() { } • PI es final: es una constante, no puede public Circulo( double nuevoRadio, Punto nuevaPosicion ) { cambiarse. Esto evita modificaciones setRadio( nuevoRadio ); accidentales por parte del programador setPosicion( nuevaPosicion ); } • Sobrecarga de constructores public Circulo( double nuevoRadio, int posicionX, int posicionY ) { • Constructor “de copia”: Circulo(Circulo setRadio( nuevoRadio ); circulo). Con este constructor se hace un posicion = new Punto( posicionX, posicionY ); círculo que es una copia del objeto que se } pasa como argumento (circulo) public Circulo( Circulo circulo ) { • ¿Por qué no hace falta import de la clase setRadio( circulo.getRadio() ); “Punto”? Porque está en el mismo paquete 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(); } Indice 63 }
  • 64. 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. Indice 64
  • 65. El proyecto de las figuras. La visualización package figuras.presentacion; Aspectos a resaltar: import figuras.dominio.*; • Modularidad: separamos la presentación (“VistaFiguras”) de las clases de dominio public class VistaFiguras { de problema (puntos, círculos, etc.) • Sobrecarga de constructores public static void mostrar( Circulo cir ) { • ¿Por qué hace falta import de las clases System.out.println( cir.toString() ); del paquete “figuras.dominio”? Porque } dichas clases están en un paquete diferente al de “VistaFiguras” public static void mostrar( Rectangulo rec ) { System.out.println( rec.toString() ); } } Indice 65
  • 66. El proyecto de las figuras. El inicio package figuras.inicio; Aspectos a resaltar: import figuras.dominio.*; • Sobrecarga de constructores import figuras.presentacion.*; • Usamos constructor de copia • ¿Por qué hacen falta imports? class Inicio { • Si hubiera que hacer la clase public static void main(String[] args) { Rectangulo, ¿cómo sería? 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 ); } } Indice 66
  • 67. 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 ); Copia del valor: 11.5 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”. Indice 67
  • 68. 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”) Indice 68
  • 69. 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 ); } Indice public static void cambiarDespedida( String mensaje ) { 69 mensaje = "Hasta luego";
  • 70. Devolución de objetos Hemos 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 { public static void main(String[] args) { private String nombre; Persona ana = new Persona( "Ana", 18 ); private int edad; Persona clon_de_ana = ana.clonar(); public Persona( String nuevoNombre, int nuevaEdad ) { // Error, no existe el constructor: setPersona( nuevoNombre, nuevaEdad ); mostrarSaludo(); // Persona juan = new Persona(); } } public void setPersona( String nuevoNombre, int nuevaEdad ) { nombre = nuevoNombre; edad = nuevaEdad; Hola, acaba de crear una nueva persona: Ana } Hola, acaba de crear una nueva persona: Ana public persona clonar( ) { Ana se ha clonado a si misma/o 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); } } Indice 70
  • 71. 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 Indice 71
  • 72. Ambitos de objeto y de método package figuras.dominio; En el ejemplo de los círculos, public class Circulo { hay variables de objeto como: private Punto posicion; private double radio; – posicion static final public double PI = 3.1416; – radio public Circulo() { } Y variables de clase (PI). public Circulo( double nuevoRadio, Punto nuevaPosicion ) { setRadio( nuevoRadio ); También hay variables de setPosicion( nuevaPosicion ); método (locales a la función): } 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(); } Indice 72 }
  • 73. Á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: class Circulo { public static void main(String[] args) { private punto posicion; System.out.println( circulo.PI); private double radio; } static public double PI = 3.1416; ... • 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) • Indice 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
  • 74. 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 { Indice private punto posicion; 74