Resumen sobre Encapsulación, Herencia, Polimorfismo, Override/Overload, Interfaces, Static, Constructores e Instanciación, Acoplamiento y Coherencia

En Esta entrada encontramos un repaso con algunos puntos clave sobre la Encapsulación, Herencia, Polimorfismo, Override y Overload


  • Encapsulación, ES-UN, TIENE-UN

    • La Encapsulación ayuda a esconder la implementación tras una interface (o API).
    • El código encapsulado tiene 2 caracteristicas:
      • Las variables de instancia se mantienen privadas (Normalmente con el modificador private).
      • Los métodos getter y setter proveen acceso a estas variables de instancia.
    • ES-UN o IS-A se refiere a herencia o implementacioón.
    • ES-UN o IS-A es expresado con la palabra clave extends
    • ES-UN o IS-A es equivalente a las expresiones “hereda de”, y “es un subtipo de”.
    • TIENE-UN o HAS-A significa que una instancia de una clase “tiene una” referencia a la instancia de otra clase u otra instancia de la misma clase.
  • Herencia

    • La herencia permite a una clase ser subclase o superclase, y así heredar variables y métodos que sean publi o protected.
    • La herencia es un concepto clave que subyace a IS-A o ES-UN, polimorfismo, sustitución (Override), sobrecarga (Overload), y cast.
    • Todas las clases (excepto la clase Object), son subclases del tipo Object y por lo tanto heredan los métodos de Object.
  • Polimorfismo

    • Polimorfismo significa “Múltiples formas”.
    • Una variable de referencia es siempre única, de tipo inmutable, pero puede referirse a un objeto de un subtipo.
    • Un objeto individual puede ser referido por una variable de referencia de otro tipo diferente (Siempre que ellos sean del mismo tipo o supertipo).
    • El tipo de la variable de referencia (no el tipo del objeto), determina cual métodos pueden ser llamados.
    • Las invocaciones de métodos polimorfos se aplican solo a métodos de instancia sustituidos.
  • Overriding y Overloading

    • Los métodos pueden ser sustituidos o sobrecargados, los constructores pueden ser sobrecargados pero no ssutituidos.
    • Los métodos abstractos deben ser sustituidos por la primera subclase concreta.
    • Respecto al método que sustituye, el método sustituido:
      • Debe tener la misma lista de argumentos.
      • Debe tener el mismo tipo de retorno, excepto como en Java 5, el tipo de retorno puede ser una subclase.
      • No debe tener un modificador de acceso mas restrictivo.
      • Puede tener un modificador de acceso menos restrictivo.
      • No debe lanzar nuevas o mas amplias excepciones marcadas.
      • Puede lanzar menos o mas estrechas excepciones, o cualquier excepción sin marcar.
    • Los métodos marcados como final no pueden ser sustituidos.
    • Solo los métodos heredados pueden ser sustituidos, y recordemos que los métodos marcados como private no son heredados.
    • Una subclase usa super.overriddenMethodName() para llamar a la versión de la superclase del método sustituido.
    • Sobrecargar significa reusar el nombre de un método, pero con unos argumentos diferentes.
    • Los métodos sobrecargados:
      • Deben tener una lsita de argumentos diferentes.
      • Puede tener diferentes tipos de retorno, si la lista de argumentos es tambien diferente.
      • Pueden tener diferentes modificadores de acceso.
      • Puede lanzar diferentes excepciones.
    • Los métodos de una superclase pueden ser sobrecargados en la subclase.
    • El polimorfismo se aplica a la sustitución (Override), no a la sobrecarga (Overload).
    • El tipo de objeto (no el tipo de variable de referencia), determina cuales métodos sustituidos son usados en tiempo de ejecución.
    • El tipo de referencia determina cuales métodos sobrecargados serán usados en tiempo de compilación.
  • Casting de Variables de Referencia

    • Hay 2 tipos de casting en variables de referencia: downcasting y upcasting.
    • Downcasting: Si tenemos una variable de referencia que se refiere a un objeto que es subtipo, podemos asignarle a la variable de referencia del subtipo. Debemos hacer un cast explícito para poder hacerlo, y el resultado es que podemos acceder a los miembros dl subtipo con la nueva variable de referencia.
    • Upcasting: Podemos asignar la variable de referencia a una variable de referencia de un supertipo de manera expícita e implícita. Esto es una operación inherente segura porque la asignación restringe las capacidades de acceso de la nueva variable.
  • Implementando una Interface

    • Cuando implementamos una interface, estamos cumpliendo su contrato.
    • Implementaremos una interface cuando propiamente y concretamente sustituyamos todos los métodos definidos por la interface.
    • Una clase individual puede implementar varias Interfaces.
  • Tipos de Retorno

    • Los métodos sobrecargados pueden cambiar los tipos de retorno, los métodos sustituidos no pueden, excepto en el caso de retornos covariantes.
    • Los tipos de retorno de la referencia del objeto puede aceptar null como valor de retorno.
    • Un array es un tipo de retorno legal, ambos se declaran y se retornan como un valor.
    • Para métodos con tipos de retorno primitivos, cualquier valor puede ser implícitamente convertido al tipo de retorno para ser retornado.
    • No se puede retornar nada desde un void, pero podemos retornar nada. Podemos poner return en cualquier método con un tipo de retorno void, para salir antes del método. Pero no podemos retornar nada de un método con un tipo de retorno que no sea non-void.
    • Métodos con un tipo de retorno a una referencia de un objeto, puede retornar un subtipo.
    • Métodos con un tipo de retorno que sea una interface, puede retornar cualquier implementación de este.
  • Constructores e Instanciación

    • Un constructor siempre es invocado cuando un objeto es creado.
    • Cada superclase en un arbol de herencia de un objeto tendrá su constructor llamado.
    • Todas las clases, incluso una clase abstracta, tiene al menos un constructor.
    • Los constructores deben tener el mismo nombre que la clase.
    • Los constructores no tienen tipo de retorno. SI vemos código con un tipo de retorno, es un método con el mismo nombre que la clase, pero no es un constructor.
    • La ejecución típica de los constructores es la siguiente:
      • El constructor llama al constructor de su superclase, el cuál llama al constructor de su superclase, y así hasta lelgar al constructor de la clase Object.
      • El constructor de Object se ejecuta y vuelve al constructor que lo ha llamado, el cual se completa y vuelve al constructor que lo ha llamado, y así baja hasta completar todas las llamadas y volver a la isntancia donde ha sido creada.
    • Los constructores pueden usar cualquier modificador de acceso, excepto private.
    • El compilador creará un constructor por defecto si no hemos creado un constructor en nuestra clase.
    • El constructor por defecto es un constructor sin lista de argumentos y con una llamada a super() sin argumentos.
    • La primera sentencia de cada constructor debe ser una llamada o a this() (constructor sobrecargado) o a super().
    • Los miembros de instancia son accesibles solo despues de que el constructor se ejecute.
    • Las clases abstractas tienen constructores que son llamados cuando una subclase concreta es instanciada.
    • Las Interfaces no tienen constructores.
    • Si una superclase no tiene un constructor sin argumentos, debemos crear un constructor e insertar una llamada a super() con argumentos que sean iguales que los del constructor de su superclase.
    • Los constructores nunca son heredados, así que no pueden ser sustituidos (Override).
    • Un constructor puede ser directamente invocado solo por otro constructor (usando una llamada a super() o a this()).
    • Problemas con las llamadas a this():
      • Puede aparecer solo como la primera sentencia en un constructor.
      • La lista de argumentos determina cual constructor sobrecargado será llamado.
      • Los constructores pueden llamar a constructores que pueden llamar a constructores, y etc, pero tarde o temprano alguno de ellos llamará a super() o la pila explotará.
      • Las llamadas a this() y super() no pueden estar en el mismo constructor. Podemos tener una o otra, pero no ambas.
  • Static

    • Se usan métodos static para implementar comportamientos que no sean afectados por el estado de cualqueir instancia.
    • Se usan variables static para mantener información que son específicas de la clase en vez de específicas de la instancia.
    • Todos los miembros static pertenecen a la clase, no a cualquier instancia.
    • Un método static no puede acceder a una variable de instancia directamente.
    • Usando el operador . podemos acceder a los miembros static, pero recordemos que usar una variable de referencia este operador es realmente un truco en la sintaxis, y el compilador sustituirá el nombre de la clase por la variable de referencia, por ejemplo:
                          d.doStuff();
                         	

      sería:

                          Dog.doStuff();
                          
    • Los métodos static no pueden ser sustituidos, pero pueden ser redefinidos.
  • Acoplamiento y Cohesión

    • El acoplamiento se refiere al grado en el cual una clase conoce sobre otra o uses miembros de otra clase.
    • La pérdida de acoplamiento es el estado deseado de tener las clases bien encapsuladas, minimizando las referencia entre uno y otro, y limitar la aplitud del uso de la API.
    • Un acoplamiento estricto es el estado indeseado de tener clases que rompan las reglas de la pérdida de acoplamiento.
    • La cohesión se refiere al grado en el cual una clase tiene un rol bien definido o responsabilidad individual.
    • Una alta cohesión es el estado deseado de una clase cuyos miembros soportan un rol bien enfocado y una responsabilidad individual.
    • Una baja cohesión es un estado indeseado de uan clase cuyos miembros soportan múltiples roles o responsabilidades.


Con esto tenemos un buen resumen sobre lo que hemos estado viendo, y siempre podemos echarle un vistazo si nos asaltan las dudas sobre algún tema de estos en particular, ahora solo falta practicar para lograr dominarlo todo desde el punto de la práctica.

Sin más cualquier aporte o corrección es bienvenida!!

Saludos!!!