Apuntes de C# Java
Apuntes de C# Java
de C# Java
Apuntes de Java 2
Apuntes de Java
Contenido
Apuntes de Java ............................................................................................................................ 2
Variables y Tipos de Datos ............................................................................................................ 4
Tipos de datos básicos (o primitivos) ............................................................................................ 4
Entrada y salida básica .................................................................................................................. 5
Salida por pantalla..................................................................................................................... 5
Entrada por teclado................................................................................................................... 5
Instrucciones ................................................................................................................................. 5
Concepto de instrucción ........................................................................................................... 5
Instrucciones básicas................................................................................................................. 6
Definiciones de variables locales........................................................................................... 6
Asignaciones .......................................................................................................................... 6
Instrucciones condicionales ...................................................................................................... 6
Instrucción if .......................................................................................................................... 6
Instrucción switch ................................................................................................................. 7
Instrucciones iterativas ............................................................................................................. 7
Instrucción while ................................................................................................................... 7
Instrucción do...while ............................................................................................................ 8
Instrucción for ....................................................................................................................... 9
Instrucción for-each .............................................................................................................. 9
Funciones .................................................................................................................................... 10
Concepto de función ............................................................................................................... 10
Definición de funciones ........................................................................................................... 10
Llamada a funciones................................................................................................................ 11
Tipos de parámetros. Sintaxis de definición ........................................................................... 11
Parámetros de entrada ....................................................................................................... 11
Arrays .......................................................................................................................................... 12
Arrays multidimensionales ...................................................................................................... 13
Tamaños de un array multidimensional.............................................................................. 14
Cadenas de texto......................................................................................................................... 15
La clase StringBuilder .............................................................................................................. 16
Listas ............................................................................................................................................ 17
Apuntes de Java 3
Ficheros ....................................................................................................................................... 20
Excepciones ............................................................................................................................. 20
Ficheros de texto ..................................................................................................................... 21
Escritura en ficheros de texto ............................................................................................. 21
Lectura en ficheros de texto ............................................................................................... 21
Ficheros binarios ..................................................................................................................... 22
Escritura en ficheros binarios .............................................................................................. 22
Lectura en ficheros binarios ................................................................................................ 23
Funciones de Ficheros y Directorios ....................................................................................... 23
Comprobar si existe un fichero ........................................................................................... 24
Realizar operaciones con ficheros....................................................................................... 24
Obtener el listado de un directorio ..................................................................................... 24
Programación Orientada a Objetos............................................................................................. 25
Clases y Objetos ...................................................................................................................... 25
Conceptos fundamentales ...................................................................................................... 26
Control de Acceso a métodos y atributos ............................................................................... 27
Definición de una Clase en Java .............................................................................................. 27
Constructores .......................................................................................................................... 28
Propiedades............................................................................................................................. 28
Variables y Tipos de Datos 4
<tipoVariable> <nombreVariable>;
C# también proporciona una sintaxis más sencilla con la que podremos asignar un valor
a una variable en el mismo momento se define. Para ello se la ha de definir usando esta
otra notación:
Los tipos de datos básicos son ciertos tipos de datos tan comúnmente utilizados en la
escritura de aplicaciones que en Java se ha incluido una sintaxis especial para tratarlos.
int a = 2;
El valor que por defecto se da a los campos de tipos básicos consiste en poner a cero toda
el área de memoria que ocupen. Esto se traduce en que los campos de tipos básicos
numéricos se inicializan por defecto con el valor 0, los de tipo bool lo hacen con false,
los de tipo char con ‘\u0000’, y los de tipo String con null.
Entrada y salida básica 5
Este ejemplo nos mostrará por pantalla el número 2 (que es el valor de a).
Para usar este método, primero tendremos que colocar la línea: import java.util.Scanner
justo al principio de nuestro programa, debajo de la primera línea “package”. Una vez
hecho esto, dentro de la función main, tendremos que crear una variable de tipo
Scanner. Y por fin, podremos leer valores usando esta variable. A continuación,
veremos un ejemplo en el que se lee un valor y se guarda en la variable a.
package com.company;
import java.util.Scanner;
Instrucciones
Concepto de instrucción
Toda acción que se pueda realizar en el cuerpo de un método, como definir variables
locales, llamar a métodos, asignaciones y muchas cosas más que veremos a lo largo de
este tema, son instrucciones.
Instrucciones 6
Toda variable que se defina dentro de un bloque de instrucciones sólo existirá dentro de
dicho bloque. Tras él será inaccesible y podrá ser destruida por el recolector de basura.
Por ejemplo, este código no es válido:
public void f();
{
{ int b; }
b = 1; // ERROR: b no existe fuera del bloque donde se declaró.
}
Instrucciones básicas
Definiciones de variables locales
Las variables locales son variables que se definen en el cuerpo de los métodos y sólo son
accesibles desde dichos cuerpos. La sintaxis para definirlas es la siguiente:
También pueden definirse varias variables en una misma instrucción separando sus
pares nombre-valor mediante comas. Por ejemplo:
int a=5, b, c=-1;
Asignaciones
Una asignación es simplemente una instrucción mediante la que se indica un valor a
almacenar en un dato. La sintaxis usada para ello es:
<destino> = <origen>;
Instrucciones condicionales
Las instrucciones condicionales son instrucciones que permiten ejecutar bloques de
instrucciones sólo si se da una determinada condición. En los siguientes subapartados de
este epígrafe se describen cuáles son las instrucciones condicionales disponibles en C#
Instrucción if
La instrucción if permite ejecutar ciertas instrucciones sólo si se da una determinada
condición. Su sintaxis de uso es la sintaxis:
Instrucciones 7
if (<condición>)
<instruccionesIf>
else
<instruccionesElse>
Instrucción switch
La instrucción switch permite ejecutar unos u otros bloques de instrucciones según el
valor de una cierta expresión. Su estructura es:
switch (<expresión>)
{
case <valor1>: <bloque1>
break;
case <valor2>: <bloque2>
break;
...
default: <bloqueDefault>
break;
}
Los valores indicados en cada rama del switch han de ser expresiones constantes que
produzcan valores de algún tipo básico entero, de una enumeración, de tipo char o de tipo
string. Además, no puede haber más de una rama con el mismo valor. En realidad, aunque
todas las ramas de un switch son opcionales siempre se ha de incluir al menos una.
Además, la rama default no tiene porqué aparecer la última si se usa, aunque es
recomendable que lo haga para facilitar la legibilidad del código.
Instrucciones iterativas
Las instrucciones iterativas son instrucciones que permiten ejecutar repetidas veces una
instrucción o un bloque de instrucciones mientras se cumpla una condición. Es decir,
permiten definir bucles donde ciertas instrucciones se ejecuten varias veces. A
continuación, se describen cuáles son las instrucciones de este tipo incluidas en C#.
Instrucción while
La instrucción while permite ejecutar un bloque de instrucciones mientras se dé una cierta
instrucción. Su sintaxis de uso es:
Instrucciones 8
while (<condición>)
<instrucciones>
Por otro lado, dentro de las <instrucciones> de un while pueden usarse dos instrucciones
especiales:
• break;: Indica que se ha de abortar la ejecución del bucle y continuarse ejecutando
por la instrucción siguiente al while.
• continue;: Indica que se ha de abortar la ejecución de las <instrucciones> y
reevaluarse la <condición> del bucle, volviéndose a ejecutar la <instrucciones> si es
cierta o pasándose a ejecutar la instrucción siguiente al while si es falsa.
Instrucción do...while
La instrucción do...while es una variante del while que se usa así:
do
<instrucciones>
while(<condición>);
Instrucción for
La instrucción for es una variante de while que permite reducir el código necesario para
escribir los tipos de bucles más comúnmente usados en programación. Su sintaxis es:
for (<inicialización>; <condición>; <modificación>)
<instrucciones>
Al igual que con while, dentro de las <instrucciones> del for también pueden incluirse
instrucciones continue; y break; que puedan alterar el funcionamiento normal del bucle.
Instrucción for-each
Existe en Java una variante de la instrucción for pensada especialmente para compactar
la escritura de códigos donde se realice algún tratamiento a todos los elementos de una
colección, que suele un uso muy habitual de for en los lenguajes de programación que lo
incluyen. La sintaxis que se sigue a la hora de escribir esta instrucción for-each es:
for (<tipoElemento> <elemento> : <colección>)
<instrucciones>
Funciones
Concepto de función
Una función es un conjunto de instrucciones a las que se les da un determinado nombre
de tal manera que sea posible ejecutarlas en cualquier momento sin tenerlas que reescribir
sino usando sólo su nombre. A estas instrucciones se les denomina cuerpo de la función,
y a su ejecución a través de su nombre se le denomina llamada a la función.
La ejecución de las instrucciones de una función puede producir como resultado un objeto
de cualquier tipo. A este objeto se le llama valor de retorno del método y es
completamente opcional, pudiéndose escribir funciones que no devuelvan ninguno.
La ejecución de las instrucciones de una función puede depender del valor de unas
variables especiales denominadas parámetros de la función, de manera que en función
del valor que se dé a estas variables en cada llamada la ejecución de la función se pueda
realizar de una u otra forma y podrá producir uno u otro valor de retorno.
Al conjunto formado por el nombre de una función y el número y tipo de sus parámetros
se le conoce como signatura de la función. La signatura de una función es lo que
verdaderamente la identifica, de modo que es posible definir en un mismo tipo varias
funciones con idéntico nombre siempre y cuando tengan distintos parámetros. Cuando
esto ocurre se dice que la función que tiene ese nombre está sobrecargada.
Definición de funciones
Para definir una función hay que indicar tanto cuáles son las instrucciones que forman su
cuerpo como cuál es el nombre que se le dará, cuál es el tipo de objeto que puede devolver
y cuáles son los parámetros que puede tomar. Esto se indica definiéndolo así:
<tipoRetorno> <nombreFunción>(<parámetros>)
{
<cuerpo>
}
En <tipoRetorno> se indica cuál es el tipo de dato del objeto que la función devuelve, y si
no devuelve ninguno se ha de escribir void en su lugar.
Aunque es posible escribir funciones que no tomen parámetros, si una función los toma
se ha de indicar en <parámetros> cuál es el nombre y tipo de cada uno de ellos,
separándolos con comas si son más de uno y siguiendo la sintaxis que más adelante se
explica.
Llamada a funciones
La forma en que se puede llamar a una función depende del tipo de función de la que se
trate.
<nombreMétodo>(<valoresParámetros>)
Parámetros de entrada
Un parámetro de entrada recibe una copia del valor que almacenaría una variable del
tipo del objeto que se le pase. Por tanto, si el objeto es de un tipo valor se le pasará una
copia del objeto y cualquier modificación que se haga al parámetro dentro del cuerpo del
la función no afectará al objeto original sino a su copia; mientras que si el objeto es de un
tipo referencia entonces se le pasará una copia de la referencia al mismo y cualquier
modificación que se haga al parámetro dentro de la función también afectará al objeto
original ya que en realidad el parámetro referencia a ese mismo objeto original. Para
definir un parámetro de entrada basta indicar cuál el nombre que se le desea dar y el cuál
es tipo de dato que podrá almacenar. Para ello se sigue la siguiente sintaxis:
<tipoParámetro> <nombreParámetro>
Por ejemplo, el siguiente código define una función llamada Suma que toma dos
parámetros de entrada de tipo int llamados par1 y par2 y devuelve un int con su suma:
int Suma(int par1, int par2)
{
return par1+par2;
}
Como se ve, se usa la instrucción return para indicar cuál es el valor que ha de devolver
la función. Este valor es el resultado de ejecutar la expresión par1+par2; es decir, es la
suma de los valores pasados a sus parámetros par1 y par2 al llamarla.
En las llamadas a funciones se expresan los valores que se deseen dar a este tipo de
parámetros indicando simplemente el valor deseado. Por ejemplo, para llamar a la función
anterior con los valores 2 y 5 se haría <objeto>.Suma(2,5), lo que devolvería el valor 7.
Arrays 12
Arrays
<tipoDatos>[] <nombreArray>;
Por ejemplo, un array que pueda almacenar objetos de tipo int se declara así:
int[] array;
Con esto el array creado no almacenaría ningún objeto, sino que valdría null. Si se desea
que verdaderamente almacene objetos hay que indicar cuál es el número de objetos que
podrá almacenar, lo que puede hacerse usando la siguiente sintaxis al declararla:
<tipoDatos>[] <nombreArray> = new <tipoDatos>[<númeroDatos>];
Por ejemplo, un array que pueda almacenar 100 objetos de tipo int se declara así:
int[] array = new int[100];
Aunque también sería posible definir el tamaño del array de forma separada a su
declaración de este modo:
int[] array;
array = new int[100];
También podemos crear arrays cuyo tamaño se pueda establecer dinámicamente a partir
del valor de cualquier expresión que produzca un valor de tipo entero. Por ejemplo, para
crear un array cuyo tamaño sea el valor indicado por una variable de tipo int (luego su
valor será de tipo entero) se haría:
int i = 5;
...
int[] arrayDinamico = new int[i];
Hay que tener cuidado a la hora de acceder a los elementos del array ya que si se especifica
una posición superior al número de elementos que pueda almacenar el array se producirá
una excepción de tipo java.lang.arrayindexoutofboundsexception.
Para evitar este tipo de excepciones puede consultar el valor del campo de sólo lectura
length que está asociado a todo array y contiene el número de elementos del mismo. Por
ejemplo, para asignar un 7 al último elemento del array anterior se haría:
array[array.length – 1] = 7;
// Se resta 1 porque array.length devuelve 4 pero el último
// elemento del array es array[3]
Arrays multidimensionales
Un array multidimensional es un array cuyos elementos se encuentran organizando una
estructura de varias dimensiones. Para definir este tipo de arrays se usa una sintaxis
similar a la usada para declarar arrays unidimensionales, pero colocando cada nueva
dimensión entre corchetes. Por ejemplo, un array multidimensional de elementos de tipo
int que conste de 12 elementos puede tener sus elementos distribuidos en dos dimensiones
formando una estructura 3x4 similar a una matriz de la forma:
1 2 3 4
5 6 7 8
9 10 11 12
Arrays 14
int[][] arrayMultidimensional;
Aunque los ejemplos de arrays multidimensionales hasta ahora mostrados son de arrays
de dos dimensiones, en general también es posible crear arrays de cualquier número de
dimensiones. Por ejemplo, un array que almacene 24 elementos de tipo int y valor 0 en
una estructura tridimensional 3x4x2 se declararía así:
El acceso a los elementos de un array multidimensional es muy sencillo: sólo hay que
indicar los índices de la posición que ocupe en la estructura multidimensional el elemento
al que se desee acceder. Por ejemplo, para incrementar en una unidad el elemento que
ocupe la posición (1,3,2) del array anterior se haría (se indexa desde 0):
arrayMultidimensional[0][2][1]++;
Para obtener el tamaño de la segunda dimensión (que en este caso es 4) tendríamos que
escribir:
En este caso podemos escribir entre los corchetes cualquiera de las filas del array, porque
todas las columnas tienen el mismo tamaño. En el caso en el que estemos usando un array
con filas de diferente tamaño, tendríamos que ir leyendo la longitud de cada fila usando
array[fila].length.
Cadenas de texto 15
Cadenas de texto
Una cadena de texto no es más que una secuencia de caracteres Unicode. En Java se
representan mediante objetos del tipo tipo de dato llamado String.
Las cadenas de texto suelen crearse a partir literales de cadena o de otras cadenas
previamente creadas. Ejemplos de ambos casos se muestran a continuación:
String cadena1 = “José Antonio”;
String cadena2 = cadena;
En el primer caso se ha creado un objeto string que representa a la cadena formada por la
secuencia de caracteres José Antonio indicada literalmente (nótese que las comillas
dobles entre las que se encierran los literales de cadena no forman parte del contenido de
la cadena que representan, sino que sólo se usan como delimitadores de la misma). En el
segundo caso la variable cadena2 creada se genera a partir de la variable cadena1 ya
existente, por lo que ambas variables apuntarán al mismo objeto en memoria.
Al igual que el significado del operador == ha sido especialmente modificado para trabajar
con cadenas, lo mismo ocurre con el operador binario +. En este caso, cuando se aplica
entre dos cadenas o una cadena y un carácter lo que hace es devolver una nueva cadena
con el resultado de concatenar sus operandos. Así por ejemplo, en el siguiente código las
dos variables creadas almacenarán la cadena “Hola Mundo”:
public static void main(String[] args)
{
String cadena = “Hola” + “ Mundo”;
String cadena2 = “Hola Mund” + ‘o’;
}
Por otro lado, el acceso a las cadenas se hace de manera similar a como si de un array de
caracteres se tratase: su función length almacenará el número de caracteres que la forman
y para acceder a sus elementos se utiliza el método charAt(). Por ejemplo, el siguiente
código muestra por pantalla cada carácter de la cadena Hola en una línea diferente:
public static void main(String[] args)
{
String cadena = “Hola”;
System.out.println(cadena.charAt(0));
System.out.println(cadena.charAt(1));
System.out.println(cadena.charAt(2));
System.out.println(cadena.charAt(3));
}
Sin embargo, hay que señalar una diferencia importante respecto a la forma en que se
accede a las tablas: las cadenas son inmutables, lo que significa que no es posible
modificar los caracteres que las forman.
Cadenas de texto 16
Aparte de los métodos ya vistos, en la clase String se definen muchos otros métodos
aplicables a cualquier cadena y que permiten manipularla. Los principales son:
if(cadena1.compareTo(cadena2) == 0)
{
System.out.println("Las cadenas son iguales");
}
La clase StringBuilder
En Java existe también la clase StringBuilder. Esta clase es similar a la clase String y nos
permitirá modificar el contenido de nuestra cadena. Como en la mayoría de los casos el
resultado final lo querremos como String, lo que haremos si necesitamos modificar una
cadena es crear un StringBuilder con nuestra cadena, modificarla y después convertirlo a
String de nuevo para dar el resultado.
Listas 17
String s = "Ejemplo";
StringBuilder sb = new StringBuilder(s);
sb.reverse();
s = sb.toString();
Listas
Una lista es una colección que nos permite guardar elementos del mismo tipo, de la
misma forma que hace un array. Al contrario que en los arrays, las listas no tienen un
tamaño definido, sino que van creciendo a medida que se les añade elementos nuevos.
List<<tipoDatos>> <nombreLista>;
Además de definirla, deberemos crearla para poderla usar. En Java, existen varias
implementaciones diferentes de una lista, que se diferencian en la forma en la que se
almacenan internamente los datos. Las dos principales implementaciones son ArrayList
(donde los elementos se almacenan en un array) y LinkedList (donde los elementos se
almacenan en una lista enlazada). La diferencia entre ambas implementaciones es que
algunas operaciones son más rápidas en una y más lentas en la otra.
Habréis visto que en lugar de int estamos escribiendo Integer en el tipo de datos que
metemos en la lista. Esto es porque en Java no se pueden crear listas de los tipos
primitivos (int, double, etc.). En lugar de éstos, habrá que usar otros tipos prácticamente
equivalentes (pero que nos darán algún que otro problema al convertir de uno al otro)
que sí podremos meter dentro de nuestras listas.
A continuación, tenéis una tabla con los tipos que tendremos que usar:
Las listas se usan de manera similar a los arrays, con unas cuantas diferencias:
• Las listas no tienen un tamaño definido, por lo que a la hora de crearlas no hay
que especificar el tamaño.
Para añadir un nuevo dato a la lista, usaremos la función add(), que nos añade un
elemento en la última posición. Así, iremos añadiendo todos los valores que
necesitemos.
lista.Add(25);
• En Java no podemos acceder a los elementos de una lista usando el operador [].
Para acceder a cada elemento, usaremos get(posición).
lista.set(2, 100);
• Para saber cuántos elementos hay en una lista, usaremos la función size(). En un
array usábamos length() que nos devolvía el tamaño que habíamos reservado.
System.out.println(lista.size());
Listas 19
Salvo estas diferencias, una lista se puede usar básicamente de la misma forma que se
usa un array. No obstante, las listas disponen de funciones específicas que nos
permiten realizar las operaciones más comunes. A continuación, se enumeran las más
importantes:
• int indexOf(<tipo dato> valor): Nos devuelve la posición del elemento, si existe. Si
el elemento no existe, nos devolverá -1.
• bool contains(<tipo dato> valor): Nos devuelve true si el valor existe dentro de la
lista y false en caso contrario.
• void clear():Elimina todos los elementos de la lista y nos la deja preparada para
volver a introducir datos.
• bool remove(<tipo dato> valor): Elimina la primera vez que aparece el valor dentro
de la lista. Nos devolverá true si ha encontrado y borrado el valor y false si el
valor no se ha encontrado dentro de la lista.
lista.remove(Integer.valueOf(2));
Collections.sort(lista);
Collections.reverse(lista);
Ficheros 20
Ficheros
Los ficheros nos permiten guardar y recuperar información desde los dispositivos de
almacenamiento. Básicamente, hay dos tipos de ficheros: ficheros de texto y ficheros
binarios. Ambos funcionan de manera similar, pero en los ficheros de texto sólo podemos
guardar cadenas de caracteres mientras que en los ficheros binarios podemos guardar todo
tipo de datos.
El proceso para utilizar un archivo consta de tres pasos: apertura del fichero, lectura y
escritura de datos, y cerrado del fichero. En Java, utilizaremos diferentes instrucciones
para los ficheros de texto y los ficheros binarios, y también diferentes opciones según
queramos leer o escribir en el fichero.
Excepciones
Antes de explicar los ficheros en Java, necesitamos hablar de las excepciones. Una
excepción se produce cuando hay algún tipo de error a la hora de ejecutar el programa
(por ejemplo, cuando nos salimos de los límites de un array). En el caso de los ficheros,
se pueden producir muchos tipos de excepciones (que el fichero no exista, que no se pueda
abrir, que no tenga los datos que creíamos que tenía…) por lo que Java nos obliga a
gestionar las excepciones que se puedan producir.
Esto se hace mediante la estructura try-catch. Básicamente, todo lo que metamos dentro
de un try estará protegido si se producen excepciones. Si se produce alguna excepción,
se ejecutará el código que hay en el catch para mostrar o corregir el error.
try
{
// ... código ...
}
catch(Exception e)
{
System.out.println("ERROR: " + e.getMessage();
}
En el ejemplo, pondremos una instrucción en el catch que nos mostrará el error por
pantalla.
Ficheros de texto
Una vez tengamos el fichero abierto, usaremos un BufferedWriter, que nos permitirá
escribir texto en el fichero.
Una vez abierto, podremos escribir texto en él. La función a utilizar será write. Esta
función sólo nos permitirá escribir cadenas. Si queremos escribir cualquier otro valor
siempre podremos convertirlo a cadena con String.valueOf.
int n = 90;
bw.write(String.valueOf(n));
Si queremos escribir en diferentes líneas usaremos ‘\n’ para para saltar a la línea
siguiente.
bw.write("Hola\n");
Cuando hayamos terminado de escribir todo el fichero, deberemos cerrarlo para que se
guarden completamente los datos en el disco. Deberemos cerrar tanto el BufferedWriter
como el FileWriter.
bw.close();
fw.close();
Para leer texto desde un fichero, primero abriremos el fichero en modo lectura:
Para leer datos del fichero, normalmente lo haremos por líneas mediante la función
readLine.
Ficheros 22
String s = br.readLine();
En principio sólo podemos leer cadenas, pero si contienen otro tipo de datos siempre
podemos convertirlo después de leerlo
int n = Integer.valueOf(s);
Si conocemos el número de líneas que contiene el fichero, podemos hacer un bucle for
para irlas leyendo, pero si no lo conocemos, tendremos que usar un método especial que
nos controla si hemos llegado al final del fichero. Aquí tenéis un ejemplo de cómo se
leería:
s = br.readLine();
while(s != null)
{
System.out.println(s);
s = br.readLine();
}
br.close();
fr.close();
Ficheros binarios
Aunque en un fichero de texto se pueden guardar datos como números enteros, números
reales, etc. (se guardan como texto, se leen con readLine y se convierten con al tipo de
datoscorrespondiente), es mucho mejor usar para ello los ficheros binarios.
Para escribir en un fichero binario, usaremos dos cosas: un FileStream para abrir el
fichero y un DataStream para poder leer y escribir diferentes tipos de datos:
dos.writeInt(7);
dos.writeDouble(2.6);
dos.writeBoolean(true);
dos.writeChar('a');
dos.writeUTF("cadena");
Cuando hayamos terminado de escribir todo el fichero, deberemos cerrarlo para que se
guarden completamente los datos en el disco.
dos.close();
fos.close();
Para leer datos desde un fichero binario también tendremos diferentes funciones
dependiendo del tipo de datos que queramos leer. Deberemos leer el tipo de datos que se
escribió originalmente en el fichero (o sea, si es un fichero de double, podremos leer
doubles pero no Strings).
int n = dis.readInt();
double d = dis.readDouble();
boolean b = dis.readBoolean();
char c = dis.readChar();
String s = dis.readUTF();
Si conocemos el número de datos que contiene el fichero, podemos hacer un bucle for
para irlos leyendo, pero si no lo conocemos, tendremos que usar una función especial que
nos avisa cuando hemos llegado al final del fichero:
while(dis.available() > 0)
{
dis.close();
fis.close();
Cuando trabajamos con ficheros, muchas veces necesitamos, además de leer o escribir
datos en el mismo, obtener información sobre el fichero. También nos suele hacer falta
obtener el contenido de un directorio. Para ello, Java cuenta con la clase File que
contiene varias funciones para trabajar con ficheros y directorios.
Ficheros 24
Una vez creado este objeto “fichero” tenemos varias funciones que nos permiten obtener
información sobre él. Para ver si un fichero existe usaremos:
if(fichero.exists())
Sin embargo, puede que un fichero exista pero no sea un fichero realmente porque Java
llama ficheros tanto a ficheros como directorios (y otras cosas más raras que nos
encontramos en los sistemas de archivos). Afortunadamente, la clase File tiene también
funciones para ver si nuestro objeto es un fichero o un directorio:
if(fichero.isFile())
if(fichero.isDirectory())
Una manera alternativa que existe en versiones de Java más modernas (desde 2011, pero
a la gente le cuesta actualizarse) es usar la clase Files (no confundir con File). La
sintaxis es similar:
if(Files.exists(Path.of("prueba.txt")))
if(Files.isRegularFile(Path.of("prueba.txt")));
if(Files.isDirectory(Path.of("prueba.txt")));
Una vez que disponemos de un objeto File, podemos realizar varias operaciones con
ficheros. Las más normales son renombrar un fichero o borrarlo.
fichero.delete();
fichero.renameTo(new File("otronombre.txt"));
Sin embargo, la “nueva” clase Files nos da más opciones, lo que nos permite además
copiar o mover un fichero:
Files.delete(Path.of("prueba.txt"));
Files.move(Path.of("prueba.txt"), Path.of("otronombre.txt"));
Files.copy(Path.of("prueba.txt"), Path.of("prueba2.txt"));
Para obtener los contenidos de un directorio también usaremos File ya que es la misma
clase para ficheros y directorios.
Con esto obtendremos un array con todos los ficheros del directorio actual (donde se ha
ejecutado el programa). Si queremos los de cualquier otra carpeta, se la pasamos por
parámetro:
Clases y Objetos
Una clase es la definición de las características concretas de un determinado tipo de
objetos. Es decir, de cuáles son los datos y los métodos de los que van a disponer todos
los objetos de ese tipo. Por esta razón, se suele decir que el tipo de dato de un objeto es
la clase que define las características del mismo.
Un objeto, por su parte, es el resultado de instanciar una clase. En este sentido, es similar
al concepto de variable.
Un atributo puede ser de cualquier tipo de datos, incluyendo otros objetos (incluso
de la misma clase).
- Métodos: son un conjunto de instrucciones a las que se les asocia un nombre de
modo que si se desea ejecutarlas basta referenciarlas a través de dicho nombre.
Son equivalentes a las funciones, pero dentro de un objeto. Dentro de estos
métodos es posible acceder con total libertad a la información almacenada en los
atributos pertenecientes a la clase dentro de la que el método se ha definido.
- Constructores: son un tipo de métodos especial que nos permiten inicializar cada
objeto.
- Propiedades: son similares a los métodos en el sentido de que contienen
instrucciones que se van a ejecutar, pero a la hora de usarlas en un programa se
comportan de manera parecida a los atributos, es decir, podemos leer datos y
escribir datos de ellas como si fueran variables. Sirven para encapsular la
información contenida en los atributos del objeto.
En Java no existen las propiedades como tales (al contrario que otros lenguajes),
pero solemos llamar propiedad al conjunto de dos funciones que nos permiten
acceder a un atributo:
o La función que nos permite leer el valor de un atributo se llama
get+nombre del atributo (ej.: getNombre). No recibirá parámetros y nos
devolverá un dato del mismo tipo que el atributo.
o La función que nos permite escribir un valor en un atributo se llama
set+nombre del atributo (ej: setNombre). No devuelve nada (es de tipo
void) y le pasamos un parámetro que será el valor que queremos almacenar
en el atributo.
Conceptos fundamentales
La programación orientada a objetos introduce nuevos conceptos, que superan y amplían
conceptos antiguos ya conocidos. Entre ellos destacan los siguientes:
• Encapsulamiento: Significa reunir a todos los elementos que pueden
considerarse pertenecientes a una misma entidad, al mismo nivel de abstracción.
Esto permite aumentar la cohesión de los componentes del sistema.
• Principio de ocultación: Cada objeto está aislado del exterior, es un módulo
natural, y cada tipo de objeto expone una interfaz a otros objetos que especifica
cómo pueden interactuar con los objetos de la clase. El aislamiento protege a las
propiedades de un objeto contra su modificación por quien no tenga derecho a
acceder a ellas, solamente los propios métodos internos del objeto pueden acceder
a su estado. Esto asegura que otros objetos no pueden cambiar el estado interno
de un objeto de maneras inesperadas, eliminando efectos secundarios e
interacciones inesperadas. Algunos lenguajes relajan esto, permitiendo un acceso
directo a los datos internos del objeto de una manera controlada y limitando el
grado de abstracción. La aplicación entera se reduce a un agregado o
rompecabezas de objetos.
• Polimorfismo: básicamente, consiste en que pueden existir dos o más métodos
con el mismo nombre dentro de una clase siempre y cuando tengan:
a) Diferente número de parámetros.
b) El mismo número de parámetros, pero de pertenecientes a diferentes
tipos de datos.
A la hora de ejecutar el método, el compilador elegirá el más apropiado de entre
los que tienen el mismo nombre.
Programación Orientada a Objetos 27
• Herencia: las clases no están aisladas, sino que se relacionan entre sí, formando
una jerarquía de clasificación. Los objetos heredan las propiedades y el
comportamiento de todas las clases a las que pertenecen. La herencia organiza y
facilita el polimorfismo y el encapsulamiento permitiendo a los objetos ser
definidos y creados como tipos especializados de objetos preexistentes. Estos
pueden compartir (y extender) su comportamiento sin tener que volver a
implementarlo. Esto suele hacerse habitualmente agrupando los objetos en clases
y estas en árboles que reflejan un comportamiento común. Cuando un objeto
hereda de más de una clase se dice que hay herencia múltiple.
Por ejemplo, si queremos definir un atributo privado de tipo entero y otro público de tipo
cadena, escribiremos:
Por ejemplo:
objeto.cadena = "hola";
objeto.insertaValor(3);
Constructores
Los constructores inicializan el estado de un objeto a la hora de crearlo. Se definen de
manera similar a los métodos, sólo que no devuelven ningún valor (en teoría devuelven
un objeto de la misma clase, pero no hace falta indicarlo ni devolverlo con un return) y
tienen que tener el mismo nombre que la clase. Así, para definir un constructor para la
clase “prueba”, escribiremos:
Los constructores se utilizan, generalmente, para darle valores iniciales a los atributos del
objeto. Al menos se debe crear un constructor por defecto (sin parámetros).
Propiedades
Las propiedades nos permiten acceder de manera controlada a los atributos de una clase.
En Java no existen las propiedades como tales, así que se simulan usando una pareja de
métodos getAtributo y setAtributo.
Aquí tenéis un ejemplo de cómo serían las propiedades básicas correspondientes al
atributo edad.:
}
}