You are on page 1of 3

Notas de clase: Programación Orientada a Objetos

Inteface

Una interfaz es declarar un conjunto de métodos. Se define igual que una clase pero en vez
de class escribimos interface. Nombre del archivo debe ser igual al nombre de la interface.
Sólo sirve para definir los métodos (es como un .h en C). Si esa clase no implementa algún
metodo de la interface debe ser abstracta.
Se las usa como una emulación de herencia multiple. Hereda de una implementa de otra. Si
una clase llama una interfaz y otra clase hereda de ella entonces esa clase también tiene los métodos
de la interfaz.
La interfaz puede ser public o default. Todos sus métodos tienen que ser públicos (lo cual
hace que la multiherencia no sea tan copada porque sólo puedo tener métodos publicos) y no static.
Las interfaces pueden ser colecciones de constantes pero en el último tiempo se dejó de usar
bastante porque a veces coleccionaba constantes que no tenían nada que ver con los métodos que
tenía. Por eso en general no esta bueno usarlo a menos que se lo haga bien.
Una variable puede ser del tipo de la interfaz y así puedo crear objetos del tipo de objetos
que implement interfaces. Puedo usar las interfaces como tipos. Puedo decir que algo es del tipo de
una interfaz.
Las clases abstractas representan el agrupamiento de comportamiento de objetos pero que no
representan ningún objeto en sí, mientras que las interfaces (cuando están orientadas a
polimorfismo) representan características. Por ejemplo un inodoro y una silla: ambas son sentables
pero obviamente hacen cosas distintas. Entonces con una interfaz le pregunto si es sentable.

Una excepción nos está diciendo que pasó algo que no era esperado (ofc)

Error tiene más que ver con la máquina virtual de java. Con las que no son runtime siempre
hay que hacer algo. Las runtime pueden llegar a ser errores del user.

Dentro de try debería estar el código que puede lanzar una excepción. Es muy común que la
gente ponga un try catch en el main (según Santi es horrible) (se lo suele hacer para que el servidor
no quede fuera de servicio) y el catch lo que hace es restartear el sistema. En el catch tenes que
poner entre parentesis el error que puede llegar a pasar (el error que agarras). Si elijo x exception y
sale y va a abortar. Podría poner catch(Exception e) para atrapar cualquiera, pero eso esta MAL.
Las excepciones no deben controlar el flujo de la aplicación.
Puedo tener muchos catch para un try ( es como un switch) y uno suele ser un Exception e
que sería como el default. Si entra a uno no entra a los demás aunque esten uno atrás del otro. Va
fijandose uno por uno como un if;elif...
Un uso típico del try;catch es en el manejo de archivos o en redes. Lo que esté dentro del
finally se ejecuta siempre, haya o no excepción.
D.instanceof(interface x) devuelve si la interface x está en D o en alguna superclase de D.
Una lista es una colección deobjetos indexable que no tiene huecos en el medio.

Colecciones

El API de java nos provee una serie de esturcturas que almacenan elementos que nos
permiten almacenarnos, procesarlos y recuperarlos cuando los necesitemos. Hay un MONTÓN, acá
vamos a ver un par. Estas colecciones son objetos que están dentro del Java collections
Frameworks (un set de interfaces, implementaciones y algunas clases que tienen algoritmos sobre
estas colecciones). Que algo sea iterable quiere decir que implementa la interfaz iterable (aunque el
array just es un caso particular). El Iterador me permite ir recorriendo la colección con un detalle: Si
alguien borra o mueve algo tiene que ser desde el iterador porque sino al recorrerlo se va a hacer un
lío bárbaro. nombreColeccion<X>, X es el tipo de valores que va a tener la colección. Sucede lo
mismo con el iterable. (Ver en java API (interfaces): Collection, list, ). Una lista en Java es
indexable. En general si te pide hacer una lista usas la abstract list.
Las implementaciones más usadas por ArrayList: ArrayList, LinkedList(una lista de nodos),
Vector (maneja concurrencias). Al usar una lista uno tipa la lista con el tipo de la interfaz. No acepta
built-in. El set intercambia un elemento por otro.
Interfaz Set, implementación HashSet, qué son? Googlear.

Para usar un Treeset o le damos una clase que implemente la interfaz comparable o le damos
una clase cualquiera y le ponemos un comparador en la creación del Treeset. Se requiere que el
x.compareTo(y) == 0 <==> el x.equals(y) devuelve true. TreeSet ordena los elementos con el orden
natural (el que me da el compareTo de String).
Clases Anónimas: Estan buenas cuando tengo clases que las voy a usar una sola vez y que
sean chiquititas. Normalmente se usan para extender otra clase o para implementar un interfaz
chiquito. La vamos a implementar en el mismo lugar donde la vamos a usar.
Mapas: Un mapa es una estructura de clave:valor. Pongo cosas en el mapa diciendoles cuál
es la clave y cuál es el valor. Formato: Map<typeKey, typeValue>. Almacena según el hash de la
key. Entonces si pongo 2 keys iguales van a tener el mismo hash y una pisa a la otra y tienen
recupero muy rápido. Atención: Las colecciones sólo almacenan referencias al objeto, por lo que si
guardo algo y luego le cambio el nombre, también cambia lo que está guardado.
Hay una clase que se llama Collections que tiene una serie de algoritmos que operan sobre
las colecciones, la mayoría opera sobre listas. Disjoint: Diferencia simétrica.

Generics
Con la generaliazción de clases via object pierdo la tipificación del dato. Por ejemplo pusheo
object, cuando lo recupero no sé qué tipo tengo. Para eso tengo que castearlo cuando lo recibo. Para
eso existe lo que se llaman tipos genéricos. Los tenemos que ver como si fueran parámetros de
clases o interfaces. Podemos enunciar entre “<” y “>” la cantidad de tipos genéricos que querramos.
Se suelen utilizar letras pero podemos poner nombres. Podemos tratar las letras como si fuesen
tipos. El parámetro de tipo puede ser una clase o una interface pero no puede ser un built-in. En
runtime el tipado genérico desaparece, sólo se utiliza en compilación porque lo único que hace es
checkeo de tipos. Por lo que si hago un Useless<String> y Useless<Integer> ambos son del
mismo tipo, Useless. Por lo que si hago: u1.getClass().equals(u2.getClass())); devuelve true.
Como el método generico sirve para tipar una instancia particular. Esta mal llamar a un
metodo de clase del tipo que le di porque los métodos de clase son independientes de las instancias,
son independientes del parámetro de tipo. Cuando queremos extender una clase o interfaz que tiene
un tipo genérico podemos elegir sostener la genericidad del tipo (no podrían ser distintos) o
podemos hacer que tome el tipo de la clase padre. Podría también tener:
MyClass<T> extends SuperClass<String> y T puede ser cualquier clase, o
MyClass<E, T> extends SuperClass<E>
El casteo siempre se hace el runtime.
@SuppressWarnings(“rawtypes”) suprime los warnings que suelen suceder usando generics.
Podemos hacer que un tipo esté limitado a ciertas condiciones (que extienda a Numbers o a
una interfaz). De esta manera si el tipo hereda algo de una clase podemos usar metodos de esa clase.
La herencia no se respeta si está tipando cosas. Un ListStack<String> no es subclase de
ListStack<Object>.
Wildcard ‘?’ te permite recibir del tipo que sea. El problema que tiene el comodín es por
ejemplo si quiero mostrar el stack saco cada elemento y lo guardo en un stack auxiliar del tipo
object e imprimo c/u y después lo vuelvo a poner. Ahí perdés el tipado porque ahora de la nada son
todos object y van a haber casos (como si es un Stack de Integer) que no vas a poder volver a poner
los cositos.
Podes recibir el wildcard pero que reciba parámetros limitados a ciertas clases que heredan
de otras. Por ejemplo ListStack<? Extends Number>. Sólo usar tipos genéricos cuando es
estrictísimamente necesario.

Un iterador es un objeto que implementa por lo menos 2 métodos


• hasNext()
• getNext()

Un set se caracteriza por no tener elementos repetidos y tener COMO MUCHO un sólo
elemento null. Algunas implementaciones de la interfaz set pueden tener más restricciones. Por
ejemplo algunas prohiben poner objetos null otras sólo permiten almacenar ciertos tipos.

Un map no es iterable así que para iterar sobre sus elementos hay que crear un
Iterator iter = map.entrySet.iterator()
El entrySet transforma el mapa en un set <K,V> y el set es iterable así que puedo crearle un iterator.
Como el set está compuesto por un par de valores, quiero que lo reciba un objeto del tipo Map.Entry
que también es de la forma <K,V> (Ojo! Vamos a necesitar castear el iterator.next() para esto (por
qué?).

You might also like