Orientación a Objetos

A continuación dejo el resumen del segundo capítulo (Object Orientation) del libro "Sun Certified Programmer for Java 6 Study Guide".

Encapsulación, ES-UN, TIENE-UN (Objetivo 5.1):
  • La encapsulación ayuda a ocultar la implementación detrás de una interfaz (API).
  • El código encapsulado tiene dos características:
    - Las variables de instancia son protegidas (generalmente con el modificador de acceso private).
    - Los métodos getter y setter proveen acceso a las variables de instancia.
  • ES-UN se relaciona con la herencia o implementación.
  • ES-UN se expresa mediante la palabra clave extends.
  • ES-UN, “hereda de”, y “es un subtipo de” son expresiones equivalentes.
  • TIENE-UN significa que una clase “tiene una” instancia de otra clase o una de su mismo tipo.

Herencia (Objetivo 5.5):
  • La herencia permite a una clase ser una subclase de una superclase, y por eso se heredan las variables y métodos (public y protected) de la superclase.
  • La herencia es el concepto clave en el que se basan los conceptos ES-UN, polimorfismo, sobreescritura, sobrecarga, y conversión de tipos (casting).
  • Todas las clases son subclases del tipo Object, y también heredan sus métodos.

Polimorfismo (Objetivo 5.2):
  • Polimorfismo significa “muchas formas”.
  • Una variable de referencia es siempre (e inalterable) de un solo tipo, pero puede referirse a un subtipo de objeto.
  • Un objeto puede ser referenciado por una variable de diferentes tipos (su mismo tipo, su subtipo, o de los tipos de interfaces que implemente).
  • El tipo de la variable de referencia (no el tipo del objeto), determina cuales pueden ser los métodos invocados.
  • Las invocaciones a métodos polimórficos se realizan solo a los métodos de instancia sobreescritos.

Sobreescritura y sobrecarga (Objetivo 1.5 y 5.4):
  • Los métodos pueden ser sobreescritos o sobrecargados; los constructores pueden ser sobrecargados pero no sobreescritos.
  • Los métodos abstractos deben ser sobreescritos por la primera subclase concreta (no abstracta).
  • Con respecto al método que sobreescribe, el método sobreescrito:
    - Debe poseer la misma lista de argumentos.
    - Debe poseer el mismo tipo de retorno, excepto a partir de Java 5, en donde el tipo de retorno puede ser una subclase (a esto se lo denomina como retorno covariante).
    - No debe poseer un modificador de acceso más restrictivo.
    - Puede poseer un modificador de acceso menos restrictivo.
    - No debe lanzar nuevas o mayores (en relación al árbol de herencia) excepciones comprobadas.
    - Puede lanzar menos o menores (en relación al árbol de herencia) excepciones comprobadas, o cualquier excepción no comprobada.
    - Los métodos finales no pueden ser sobreescritos.
  • Solo los métodos heredados pueden ser sobreescritos, y se debe recordar que los métodos privados no son heredados.
  • Las subclases deben usar el operador super.nombreDeMetodo(), para invocar las versiones de la superclase del método sobreescrito.
  • Sobrecarga significa reutilizar el nombre de un método, pero con diferentes argumentos.
  • Los métodos sobrecargados:
    - Deben poseer listas de argumentos diferentes.
    - Pueden poseer diferentes tipos de retorno, si las listas de argumentos son diferentes.
    - Pueden poseer diferentes modificadores de acceso.
    - Pueden lanzar diferentes excepciones.
  • Los métodos de una superclase pueden ser sobrecargados en una subclase.
  • El polimorfismo se encuentra en la sobreescritura, no en la sobrecarga.
  • El tipo de un objeto (no el tipo de la variable de referencia), determina que método sobreescrito es utilizado en tiempo de ejecución.
  • El tipo de la referencia determina que método sobrecargado se utilizará en tiempo de complicación.

Conversión de variables de referencia (Objetivo 5.2):
  • Existen dos tipos de conversión de variables de referencia: especificación (downcasting) y generalización (upcasting).
  • Downcasting: Con una referencia a un supertipo de objeto, se puede realizar una conversión explícita a un subtipo, para acceder a los miembros de ese subtipo.
  • Upcasting: Con una referencia a un subtipo de objeto, se puede acceder explícita o implícitamente a los miembros de la clase base.

Implementando una interface (Objetivo 1.2):
  • Cuando se implementa una interface, se está cumpliendo con su contrato.
  • Cuando se implementa una interface, lo que se hace es sobreescribir todos los métodos definidos en la misma.
  • Una clase puede implementar muchas interfaces.

Tipos de retorno (Objetivo 1.5):
  • Los métodos sobrecargados pueden cambiar su tipo de retorno; los métodos sobreescritos no, excepto en el caso de que sean tipos de retornos covariantes.
  • Los tipos de retorno de referencias a objetos pueden devolver el valor null.
  • Un arreglo es un tipo de retorno válida, siempre y cuando se declare y se retorne.
  • Los métodos con tipos primitivos de retorno, pueden realizar conversiones implícitas para devolver sus valores.
  • Los métodos con retorno void, no pueden devolver nada. Es decir, se puede utilizar la palabra clave return para finalizar la ejecución del método, pero no se puede devolver ningún tipo de valor, salvo void.
  • Los métodos con referencias a objetos como tipo de retorno, pueden devolver subtipos.
  • Los métodos con una interface como tipo de retorno, pueden devolver cualquier instancia de una clase que la implemente.

Constructores e instanciación (Objetivo 1.6 y 5.4):
  • Un constructor es invocado siempre que un objeto es creado.
  • Para instanciar un objeto, cada superclase en el árbol de herencia posee un constructor que es invocado.
  • Cada clase, incluso las clases abstractas, poseen al menos un constructor.
  • Los constructores deben poseer el mismo nombre que la clase.
  • Los constructores no poseen un tipo de retorno. Si posee un tipo de retorno no es un constructor, sino un simple método con el mismo nombre que la clase.
  • La ejecución típica de los constructores se realiza de la siguiente manera:
    - El constructor invoca al constructor de su superclase, el cuál invoca al constructor de su superclase, y sigue así a través de todo el árbol de herencia hasta alcanzar el constructor de la clase Object.
    - Se ejecuta el constructor de la clase Object y luego se continúa con la ejecucióncorrespondiente al constructor de la primera subclase (de Object). Se sigue el mismo proceso “hacia abajo” hasta finalizar la ejecución del constructor que desencadeno las distintas creaciones.
  • Los constructores pueden utilizar cualquier modificador de acceso.
  • El compilador crea un constructor por default, si no se crea ningún constructor explícito en la clase.
  • El constructor por default no posee argumentos, y posee una llamada al constructor sin argumentos de su clase padre super().
  • La primera línea de todos los constructores debe ser this() (si es un constructor sobrecargado) o super().
  • El compilador agregará una llamada a super() (implícita) a menos que se especifique una llamada a this() o super().
  • Los miembros de instancia son accesibles solo después de la ejecución del constructor del supertipo.
  • Las clases abstractas poseen constructores, los cuales son invocados cuando una subclase concreta se instancia.
  • Las interfaces no poseen constructores.
  • Si una superclase no posee un constructor sin argumentos, es aconsejable crear un constructor sin argumentos el cuál invoque a alguno de los constructores existentes pasando parámetros por defecto.
  • Los constructores nunca son heredados, y por lo tanto no pueden ser sobreescritos.
  • Un constructor solo puede ser invocado directamente por otro constructor, a través de las palabras clave this() o super().
  • Características de la llamada this():
    - Puede estar solo en la primera línea de un constructor.
    - La lista de argumentos determina que constructor sobrecargado es invocado.
  • Los constructores pueden invocar otros constructores, y así sucesivamente. Pero tarde o temprano se deberá invocar a super(), ya que si no se arrojará una excepción relacionada a la pila.
  • Las invocaciones a this() y super() no pueden estar en un mismo constructor. Se puede tener uno u otro, pero nunca ambos.

Estáticos (Objetivo 1.3):
  • Los métodos estáticos son utilizados para implementar comportamientos que no están afectados por el estado de ninguna instancia.
  • Las variables estáticas se utilizan para almacenar información que es específica de la clase. Existe solo una copia de las variables estáticas.
  • Todos los miembros estáticos pertenecen a la clase, no a una instancia.
  • Un método estático no puede acceder a una variable de instancia directamente.
  • Para acceder a los miembros estáticos se utiliza el operador punto (.). Se debe recordar que la utilización de una instancia para acceder a un miembro estático es solo un truco, ya que el compilador sustituye la variable de referencia por el nombre de la clase.
  • Los métodos estáticos no pueden ser sobreescritos, pero si pueden ser redefinidos.

Acoplamiento y cohesión (Objetivo 5.1):
  • El acoplamiento se refiere al grado en que una clase conoce o usa los miembros de otra clase.
  • Bajo acoplamiento es el estado deseado para tener clases que estén bien encapsuladas, minimizadas las referencias entre ellas, y se limitan al uso de las API’s.
  • Alto acoplamiento es el estado indeseado de tener clases que no respetan las reglas de bajo acoplamiento.
  • La cohesión se refiere al grado en que una clase, cumple un rol bien definido o tiene una responsabilidad específica.
  • Alta cohesión es el estado deseado de una clase que posee un rol bien definido.
  • Baja cohesión es el estado indeseado de una clase que posee muchos roles y demasiadas responsabilidades.

2 comentarios:

Matías Emiliano Alvarez Durán dijo...


Que suerte que te haya gustado, estoy invirtiendo mucho tiempo en esto (tanto la preparación del exámen como el blog). Espero tener noticias tuyas relacionadas a tu preparación. Cualquier aporte será bienvenido.
Saludos

arcioneo dijo...


Y si el problema es tal que asi?


public class A {
//primitives
//public void m(byte a){System.out.println("I am byte");}
//public void m(short a){System.out.println("I am short");}
//public void m(char a){System.out.println("I am char");}
//public void m(int a){System.out.println("I am int");}
//public void m(long a){System.out.println("I am long");}
//public void m(float a){System.out.println("I am float");}
//public void m(double a){System.out.println("I am double");}
//wrappers
public void m(Byte a){System.out.println("I am Byte");}
public void m(Short a){System.out.println("I am Short");}
public void m(Character a){System.out.println("I am Character");}
public void m(Integer a){System.out.println("I am Integer");}
public void m(Long a){System.out.println("I am Long");}
public void m(Float a){System.out.println("I am Float");}
public void m(Double a){System.out.println("I am Double");}
//object
public void m(Object a){System.out.println("I am Object");}
//parametros variantes primitivos
public void m(byte... a){System.out.println("I am byte...");}
public void m(short... a){System.out.println("I am short...");}
public void m(char... a){System.out.println("I am char...");}
public void m(int... a){System.out.println("I am int...");}
public void m(long... a){System.out.println("I am long...");}
public void m(float... a){System.out.println("I am float...");}
public void m(double... a){System.out.println("I am double...");}
//parametros variantes wrappers
public void m(Byte... a){System.out.println("I am Byte...");}
public void m(Short... a){System.out.println("I am Short...");}
public void m(Character... a){System.out.println("I am Character...");}
public void m(Integer... a){System.out.println("I am Integer...");}
public void m(Long... a){System.out.println("I am Long...");}
public void m(Float... a){System.out.println("I am Float...");}
public void m(Double... a){System.out.println("I am Double...");}
//parametros variantes object
public void m(Object... a){System.out.println("I am Object...");}
//otros mas
//public void m(Byte a, Byte b){System.out.println("I am Byte, Byte");}
//public void m(Byte []a){System.out.println("I am Byte[]");}//comentado a proposito por compilacion


}


Que pasa con las llamadas y en que orden y porque se hacen? estoy enloqueciendo con esta duda



Publicar un comentario

Este blog dejo de ser mantenido el día 12/02/2010. Para cualquier consulta o comentario realizarlo a través del sitio http://onj2ee.blogspot.com/