Está en la página 1de 17

MÓDLO 3

APLICANDO POLIMORFISMO EN JAVA


Ejemplos De Polimorfismo En Java
Formas De Declaración De Métodos
Hay dos formas de llamar a un método: usar el nombre solo, en el caso de querer llamar a
otro método de la misma clase; usar una variable que contenga una referencia a un
objeto, seguida de un punto y del nombre del método para llamar a un método del objeto
al que hace referencia; y usar el nombre de la clase y un punto, para llamar a un método
static de una clase.
Una clase puede contener métodos static para realizar tareas comunes que no requieren
un objeto de la clase. Para llamar a un método static, se especifica el nombre de la clase
en la cual está declarado el método, seguido de un punto y del nombre.

Sobrecarga De Métodos
Pueden declararse métodos con el mismo nombre en la misma clase, siempre y cuando
tengan distintos conjuntos de parámetros. A esto se lo conoce como sobrecarga de
métodos.
Ej:
public int potencia2(int x)
{
----
}
public double potencia2(double x)
{
----
}
Son dos métodos que se llaman igual, pero tienen distintos parámetros. El compilador los
diferencia y sabe cuál de los métodos “potencia2” estamos invocando.
Una Sobrecarga Típica, La Del Método Constructor
Un uso muy común de la sobrecarga es tener varios métodos constructores para una
clase.
Sobrecargar los constructores permite llevar a cabo una tarea, como inicializar objetos por
caminos distintos.

ENCAPSULAMIENTO
Se dice que un objeto encapsula datos y funcionalidad y que, además, oculta su
información, dado que solamente expone lo que quiere hacer público a otros objetos.
En la POO el encapsulamiento surge de la necesidad de usar procedimientos o funciones
(en formas de métodos) guardados en otras clases y es la expresión del reuso de
programas. Esta forma de trabajo se basa en la abstracción de procedimiento, dado que
conocemos qué esperar del método, permaneciendo oculto todo el trabajo interno; solo
nos importa la interfaz para usar o llamar al método. La interfaz mencionada es el nombre
del método y la lista de parámetros, lo que se llama signatura o firma del método.
A menudo, varios métodos comparten y usan los mismos datos y se debe asegurar que las
acciones de un método no interfieran inesperadamente con las acciones de otro método.
Así, los datos y los métodos que puedan modificarlos deben ser ocultados en un módulo.
Lo que hace esta encapsulación es crear un objeto que otros componentes del sistema
puedan usar una y otra vez. La condición es que debe estar declarado como público para
permitir el acceso de los otros métodos que lo requieran.

Control De Acceso A Los Datos


La idea detrás de usar objetos es que los datos y los métodos que tienen acceso a estos
datos están encapsulados de tal forma que ningún otro objeto externo puede acceder a
estos, excepto a través de los métodos del mismo objeto específicamente diseñados para
ello.
Para implementar el encapsulamiento, se utiliza la palabra reservada de control de acceso
private. Junto con esta primera pauta, debemos crear métodos para leer y modificar los
valores de estas variables y a ellos sí le ponemos el modificador de acceso public para que
los procesos que quieran leerlas o modificarlas puedan usarlos. Estos métodos se
denominan generalmente: Setters y Getters.
El Alcance De Los Identificadores
El alcance de un identificador es la parte del programa en donde el identificador es
conocido y donde puede ser usado.
1) Alcance definido por la construcción sintáctica: en general, un identificador es
conocido desde el punto donde es introducido hasta el final de la construcción que
lo abarca.
2) Identificadores globales: los identificadores definidos en la clase como variables,
constantes o métodos son conocidos por cualquier método contenido y se les
llama locales a la clase.
3) Variable de control para las iteraciones: un identificador introducido como un
índice de un loop for puede ser usado en cuerpo del loop for, pero no fuera de él.
Es local al loop for.
4) Sentencias estructuradas: un identificador introducido en una declaración dentro
del cuerpo de una sentencia estructurada, tal como for, while o if, puede ser usada
hasta el final de ese cuerpo. Es local al cuerpo.
5) La redefinición está prohibida: un identificador no puede ser redefinido en un
alcance donde ya es conocido. Por ejemplo, no es legal escribir una declaración de
una variable m en un alcance donde una variable m está ya definida o crear la
variable i del índice de un loop for en un alcance donde ya ha sido definido, es
decir, dentro del mismo bloque for.
6) Métodos: un método introduce un nuevo alcance. El nombre del método es
siempre conocido en el cuerpo de este y en cualquier otro método perteneciente a
la misma clase. Si el método está declarado como público en una clase, entonces,
es conocido para cualquier objeto que incorpore con import a esa clase y cuando
se crea un objeto de esa clase.
7) Re-usando identificadores: los nombres de parámetros e identificadores dentro de
un método pueden ser los mismos nombres usados en el alcance de la clase donde
está definido. Así, el identificador está siendo reusado. Si no fuera posible usar
nuevamente los identificadores, el programador escritor de un método necesita
conocer todos los identificadores globales dentro de las clases donde va a ser
usado el método y eso es difícil de establecer de antemano. Si un identificador re-
usado aparece en una sentencia dentro del método y coincide con un identificador
local (parámetro, variable o constante), este es el inmediatamente apuntado o
referenciado. Para usar una variable local con el mismo nombre, el programador
debe antepone la palabra clave this seguido por un punto.
8) Identificadores importados: los identificadores usados dentro de un método pero
no definidos ni en la lista de parámetros como en una definición local son globales
para el método. Estos identificadores deben ser definidos en la clase que los
contiene.
9) Los identificadores no pueden ser redefinidos: la regla para importar y la regla
que prohíbe redefiniciones toman sentido conjunto e indican que si un
identificador de una case está usada en un método, ese identificador no puede
subsecuentemente ser redefinido en el método.

CLASES ABSTRACTAS
A veces se requiere crear una clase, de nivel superior o del tipo superclase, que tenga las
características generales y se deja a cada subclase la tarea de completar los detalles
requeridos en cada caso. Esta clase es llamada clase abstracta.
Una clase que se declara abstracta puede incluir o no métodos abstractos, pero si una
clase posee métodos abstractos, será siempre una clase abstracta. Las clases abstractas no
pueden ser instanciadas, pero pueden ser subclasificadas.
Un método abstracto es un método sin un cuerpo. Por lo tanto, consiste en un tipo de
retorno y lista de parámetros y se precede con la palabra clave abstract. El modificador
abstract solo se puede usar en métodos normales. No se puede aplicar abstract a los
métodos estáticos o a los constructores.
Los métodos declarados abstractos en la superclase, deben ser sobre-escritos por sus
subclases obligatoriamente.

EJEMPLOS DE P.O.O. JAVA / CLASES ABSTRACTAS


A continuación, presentamos extractos útiles del manual de BlueJ:
Comenzando:
1. Para abrir un proyecto, seleccione Open del menú Project
2. Para crear un objeto, seleccione un constructor del menú emergente de la clase.
3. Para ejecutar un método, selecciónelo en el menú emergente del objeto.
4. Para editar el código fuente de una clase, haga doble-clic en su icono.
5. para compilar una clase, pulse el botón Compile del editor. Para compilar un proyecto,
pulse el botón Compile en la ventana del proyecto.
6. Para obtener ayuda para un mensaje de error de compilación, pulse la interrogación
que está próxima al mensaje de error.
Haciendo un poco más:
7. La inspección de objetos permite realizar una depuración sencilla al mostrar el estado
interno de un objeto.
8. Se puede pasar un objeto como parámetro a un método pulsando en el icono del
objeto.
Creando un nuevo proyecto:
9. Para crear un proyecto seleccione New... del menú Project.
10. Para crear una clase, pulse el botón New Class y especifique el nombre de la clase.
11. Para crear una flecha, pulse en el botón de flecha y arrástrela en el diagrama, o
simplemente escriba el código en el editor.
12. Para eliminar una clase o una flecha, seleccione la función Remove de su menú
emergente.

MÓDULO 4
ARREGLOS
Estructuras De Datos
En general con las variables y constantes es suficiente para resolver la mayoría de las
situaciones, pero en otros casos se requiere alguna organización previa de los datos a
procesar. Es por eso que se crean estructuras más complejas. En primer lugar, entre estas
estructuras encontramos a los arreglos que ofrecen una forma de almacenar varios
valores del mismo tipo y a los que podemos acceder con un índice que nos indica la
posición del valor para procesar.
En Java, los arreglos pueden tener una o más dimensiones, aunque el arreglo
unidimensional es el más común.
Los arreglos se utilizan para una variedad de propósitos, pero su ventaja principal de una
matriz es que organiza los datos de tal manera que puede ser fácilmente manipulable.
Aunque los arreglos en Java se pueden usar como en otros lenguajes de programación,
tienen un atributo especial: se implementan como objetos. La ventaja de esto es que los
arreglos no utilizados pueden ser tratados por el mecanismo de recogido de basura o
garbage collector, que permite recuperar espacio de memoria no utilizado.

Arreglos Unidimensionales
Un arreglo unidimensional es una lista de variables relacionadas. Estas listas son comunes
en la programación. Por ejemplo, puedes utilizar un array unidimensional para almacenar
los números de cuenta de usuarios en una red, o los goles de un equipo de fútbol.
Dado que los arreglos se implementan como objetos, la creación de un arreglo es un
proceso de dos pasos. Primero, declara una variable de referencia del arreglo. Segundo,
asigna memoria para el arreglo, asignando una referencia a esa posición de memoria a la
variable arreglo. Así, los arreglos en Java se asignan dinámicamente utilizando el operador
new.

Esta declaración funciona como una declaración de objeto. La variable muestra contiene
una referencia a memoria, asignada por new. Esta memoria es lo suficientemente grande
como para contener 10 elementos de tipo int.
Los límites de los arreglos se aplican estrictamente en Java. De hecho, se produce un error
en tiempo de ejecución por superar o subestimar el final de un arreglo.
Al igual que con los objetos, es posible separar la declaración precedente en dos. Por
ejemplo, en la figura 4.
Se accede a cada elemento individual dentro del array mediante el uso de un índice. Así,
el primer elemento en muestra es muestra[0].

Ej: el siguiente programa encuentra los valores mínimos y máximos almacenados en el


arreglo nums recorriéndolo mediante un bucle for.
Arreglos Multidimensionales
Los elementos de un arreglo pueden ser de cualquier tipo, incluso otro arreglo. En Java
hay una forma abreviada de declarar arreglos de dos o más dimensiones: simplemente
agregamos más dimensiones en los constructores de declaración y new.
Por ejemplo, a continuación mostramos una declaración que serviría para hacer una tabla
de multiplicar con 10 filas y 20 columnas:

La primera dimensión es el número de filas y la segunda, el número de columnas (esta es


una convención y no es importante a la hora de programar).
Incluso en los casos en que la longitud lógica del arreglo varíe, la longitud real del arreglo
debe ser determinada cuando se inicializa. Esto presenta el problema de saber de
antemano el tamaño del arreglo que necesito, lo que no siempre es posible. ¿Qué
podemos hacer?
Java nos provee de una clase, Vector, que resuelve muchos de los problemas de longitud
de los arreglos. Para hacer uso de Vector, debemos importar la clase Vector del paquete
java.util:

import java.util.Vector;

Un Vector es como un arreglo de longitud variable que puede crecer indefinidamente.


Inicialmente, un vector se construye sin celdas.
// names es un vector de nombres de personas
Vector names = new Vector();

STRINGS
CADENA DE CARACTERES EN JAVA (STRINGS)
Introducción
En Java los caracteres se almacenan en contenedores que pueden tener dos tipos de
datos, el char que es primitivo y que almacena un número con el código del carácter y el
tipo de dato de referencia String, que es una clase y que permite almacenar conjuntos de
caracteres con mayor facilidad de uso y aprovechando los métodos que tiene una clase de
Java.
Los caracteres especiales (tabulación, nueva línea, etc.) son representados por secuencias
de escape. Las secuencias de escape pueden aparecer en variables de tipo char, pero se
usan más frecuentemente en las Strings. El valor de una String es un conjunto de
caracteres delimitados por comillas.
Operaciones Básicas Con Strings
Quizás la operación más importante en las variables de tipo String es la de pegar dos
cadenas, que llamaremos concatenación. En Java la concatenación se hace con el
operador “+”.

Java tiene la capacidad de convertir todo tipo en String. Para los tipos primitivos, la String
correspondiente es la representación legible del valor del tipo primitivo elegido. Para los
objetos, Java llama al método toString (un método definido para todos los objetos) que
explícitamente construye una cadena String a partir del valor actual del objeto. Esto puede
parecer una característica extraña del lenguaje, sin embargo, es bastante útil para el
debugging.
Es posible usar la concatenación como un atajo para convertir tipos arbitrarios en su
representación String: solo concatenas el objeto a la cadena vacía.
Para determinar la longitud de una cadena de caracteres, es decir, el número de
caracteres de la cadena, podemos aplicar el método length.
Indizando Cadenas
Para desarmar una cadena, la herramienta principal es el método charAt. Este método le
permite al programador recuperar un carácter de una cadena. Para hacerlo, debemos
darle al método chatAt una posición o índice. El índice del primer carácter en un arreglo
String es cero y se incrementa de a uno hacia la derecha.

EJ: Supongamos que estás interesado en generar un titular donde las letras aparezcan
intercaladas con espacios. Por ejemplo, dado el argumento Hola, queremos generar el
valor H o l a. La siguiente función genera una String como deseamos:
Si cuando hago una salida de impresión, agrego un espacio, (“SI “), entonces ese espacio
se imprime.
Ahora voy a poner varios algoritmos de operaciones con cadenas.

Una forma alternativa toma dos parámetros: el índice del primer carácter de la subcadena
y el índice de la primera posición que sigue a la subcadena.
Comparación De Cadenas
Con tipos de datos primitivos, los operadores ==, < y > son los responsables de establecer
un orden entre valores. Al ser una clase, estos operadores no aplican para Strings. Para
comparaciones, cuentas con el método equals, que es el responsable de controlar si dos
cadenas son iguales carácter por carácter. El orden de las cadenas puede ser verificado
con el método compareTo. El orden que se considera es el orden lexicográfico o del
diccionario.

EXCEPCIONES
Introducción
Una excepción es un error que se produce en tiempo de ejecución. Usando el subsistema
de atención de excepciones de Java se pueden manejar de manera estructurada y
controlada los errores que suceden en tiempo de ejecución. El soporte de Java para
atender esta situación es más limpio y más flexible que la mayoría de los demás lenguajes.
Java permite que un programa defina un bloque de código, llamado controlador de
excepciones, que se ejecuta automáticamente cuando se produce un error. Si un error se
produce, el procesador de excepciones lo atenderá.
La Jerarquía De Excepciones
En Java, todas las excepciones están representadas por clases. Todas las clases de
excepción se derivan de una clase llamada Throwable.
Hay dos subclases directas de Throwable: Exception y Error. Las excepciones de tipo Error
están relacionadas con errores que se producen en la propia máquina virtual Java, y no en
su programa. Estos tipos de excepciones están fuera de su control y su programa no
suelen tratar con ellos.
Los errores que resultan de la actividad del programa están representados por subclases
de Exception (dividir por cero, encontrar el límite de un arreglo y los errores de archivo).
En general, tu programa deberá manejar excepciones de estos tipos. Una subclase
importante de Exception es RuntimeException, que se utiliza para representar varios tipos
de errores comunes de tiempo de ejecución (run-time errors).
Fundamentos De Manejo De Excepciones
El manejo de excepciones de Java se administra a través de cinco palabras clave: try,
catch, throw, throws y finally.
Las sentencias de programa que desean supervisar las excepciones están contenidas en un
bloque try. Si se produce una excepción dentro del bloque try, esta se activa. Su código
puede captar esta excepción utilizando catch y manejarlo de alguna manera racional. Las
excepciones generadas por el sistema son automáticamente lanzadas por el sistema de
run time de Java. Para lanzar una excepción manualmente, utilizas la palabra clave throw.
Cualquier código que deba ser ejecutado al salir de un bloque try se pone en un bloque
finally.
Las excepciones se generan de tres formas diferentes. En primer lugar, la máquina virtual
Java puede generar una excepción en respuesta a algún error interno que está fuera de su
control… En segundo lugar, las excepciones estándar, como las que corresponden a dividir
por cero o el índice de matriz fuera de los límites, se generan por errores en el código del
programa. Necesita manejar estas excepciones. En tercer lugar, puede generar una
excepción manualmente mediante la instrucción throw.
En el centro de la gestión de excepciones están try y catch. Estas palabras claves trabajan
juntas: no se puede tener un try sin un catch, o un catch sin un try.
Si no se produce ninguna excepción por un bloque try, no se ejecutarán declaraciones
catch y el control del programa se reanudará después de la instrucción catch.
Las Consecuencias De Una Excepción No Capturada
La captura de una de las excepciones estándar de Java tiene un beneficio secundario: evita
la terminación anormal del programa. Cuando se lanza una excepción, debe ser capturada
por algún pedazo de código, en alguna parte. En general, si tu programa no atiende una
excepción, entonces será capturado por la JVM. El problema es que el manejador de
excepciones por defecto de la JVM termina la ejecución y muestra un seguimiento de la
pila de proceso y un mensaje de error. Es importante que tu programa pueda manejar las
excepciones en sí, en lugar de confiar en la JVM.
El tipo de la excepción debe coincidir con el tipo especificado en una declaración de catch.
Si no lo hace, no se detectará la excepción.

MANIPULACIÓN DE ARCHIVOS
Lectura Y Escritura De Archivos Usando Flujos De Bytes
Java proporciona una serie de clases y métodos que te permiten leer y escribir archivos de
los tipos más comunes, los almacenados en un disco.
En Java, todos los archivos están orientados a bytes, y se proporcionan métodos para leer
y escribir bytes, desde y hacia un archivo. Así, leer y escribir archivos que utilizan streams
(corrientes) de bytes es muy común.
Para crear un stream de bytes vinculado a un archivo, utiliza FileInputStream o
FileOutputStream. Para abrir un archivo, simplemente crea un objeto de una de estas
clases, especificando el nombre del archivo como un argumento para el constructor. Una
vez que el archivo está abierto, puedes leer o escribir en él.
Lectura De Un Archivo
Se abre un archivo para la entrada creando un objeto FileInputStream. Aquí está su
constructor más comúnmente utilizado.

Aquí, archivoNombre especifica el nombre del archivo que desea abrir. Si el archivo no
existe, se produce la excepción FileNotFoundException.

Para leer un archivo, puedes utilizar read():


Cada vez que se llama, read() lee un solo byte del archivo y lo devuelve como un valor
entero. Devuelve -1 cuando se encuentra el final del archivo. Lanzará una excepción
IOException cuando se produce un error. Por lo tanto, esta versión de read() es la misma
que se usa para leer desde el teclado de consola.
Cuando haya terminado con un archivo, debe cerrarlo llamando a close (). Su forma
general se muestra aquí:

El cierre de un archivo libera los recursos del sistema asignados al archivo, permitiendo
que sean utilizados por otro archivo.

Escritura de un archivo
Para abrir un archivo para la salida, creas un objeto FileOutputStream. Aquí están los dos
constructores más comúnmente usados:

Si no se puede crear el archivo, se lanzará FileNotFoundException. En la primera forma,


cuando se abre un archivo de salida, se destruye cualquier archivo preexistente con el
mismo nombre. En la segunda forma, si append es true, entonces la salida se agrega al
final del archivo. De lo contrario, el archivo se sobrescribe.
Para escribir en un archivo, usarás el método write (). Su forma más simple se muestra
aquí:

Este método escribe en el archivo un byte, el especificado por byteval. Aunque byteval se
declara como un entero, solo los 8 bits de orden inferior se escriben en el archivo. Si se
produce un error, se lanza la IOException. Como es sabido, cuando se realiza la salida del
archivo, esa salida a menudo no es inmediatamente escrita en el dispositivo físico real,
sino que esa salida se almacena en búfer hasta que una cantidad considerable de datos
puede ser escrita de una vez. Esto mejora la eficiencia del sistema. Sin embargo, si deseas
forzar que los datos se deben escribir en el dispositivo físico, independientemente de que
el búfer esté lleno o no, puedes llamar al método flush(), lo que se muestra a
continuación:

El cierre de un archivo libera los recursos del sistema asignados al archivo, permitiendo
que sean utilizados por otro archivo. También asegura que cualquier salida que quede en
un búfer de disco se escriba realmente en el disco.
El siguiente ejemplo copia un archivo de texto. Los nombres de los archivos de origen y de
destino serán tomados como parámetros porque están especificados en la línea de
comandos.

También podría gustarte