Curso Java - Encapsulación, herencia y polimofismo
Bienvenidos a un capítulo más del curso de Java orientado al mundo laboral.
¿Qué tal vais?
Recordad que si tenéis dudas o cualquier aportación podéis dejar un comentario o responder a los emails.
Ya vimos una buena introducción a POO y hoy continuamos con 3 conceptos que son el pilar de esta.
Encapsulación: Aprende a proteger tus datos y mantener la seguridad de tus objetos mientras controlas cómo interactúan entre sí. Esto es el pan de cada día en tu trabajo de Java, debes conoces los ámbitos que pongo abajo.
Herencia: Descubre cómo aprovechar y extender la funcionalidad existente para evitar duplicación de código. Se suele usar, no demasiado pero la verás en los proyectos.
Polimorfismo: Entiende cómo puedes hacer para que tus objetos se comporten de maneras diferentes según el contexto. Esto hace que el código sea más dinámico y flexible. ¿En la vida real?. Apenas vas a encontrarla, si acaso hay desarrolladores muy pros en tu proyecto y buscan maneras de usarla para optimizar puntualmente 😆
Let’s go!
Encapsulación
El encapsulamiento es un principio fundamental de la Programación Orientada a Objetos (POO). Consiste en restringir el acceso directo a los datos de una clase y proporcionar métodos controlados para interactuar con ellos.
En otras palabras, protege los datos de tu objeto y asegura que sólo puedan modificarse de manera controlada.
Beneficios del encapsulamiento:
Mayor seguridad: Los datos están protegidos contra accesos no deseados.
Código más modular: Cada clase se encarga de sus propios datos.
Mantenimiento más sencillo: Es fácil cambiar la implementación interna sin afectar otras partes del programa.
¿Qué ámbito tiene cada modificador?
Aquí he hecho esta pequeña tabla para verlo mejor. Siempre acordaros que cuando decimos alcance en la misma clase o fuera de la clase, esa clase normalmente es el archivo. Por ejemplo el ClienteModel.java que construimos.
Cómo implementar el encapsulamiento en Java
Si recordáis la clase anterior, todo esto ya lo implementamos.
Paso 1: Declarar los atributos como privados
Define los campos de la clase como private para restringir el acceso directo desde otras clases.
Paso 2: Crear métodos getter y setter
Proporciona métodos públicos para acceder y modificar los atributos de manera controlada.
De esta manera, cuando instanciemos al cliente Antonio, usando
ClienteModel cliente = new ClienteModel(“Antonio”, “email”, “normal”);
Esos atributos no podrán ser modificados a no ser que se usen los métodos públicos set.
Herencia
¿Qué es la herencia?
La herencia es un mecanismo que permite que una clase (llamada clase hija o subclase) adquiera las propiedades y comportamientos de otra clase (llamada clase padre o superclase).
Piensa en nuestro proyecto y la clase Cliente. Ahora nos hemos dado cuenta de que vamos a tener clientes premium, estos clientes van a tener los mismos métodos que los de cliente pero puede que alguno más.
Todos los clientes tienen atributos comunes como su nombre y email, pero los clientes premium tienen beneficios adicionales, como un descuento. Con herencia, puedes definir una clase base Cliente con los atributos y métodos comunes, y luego extenderla para crear una clase ClientePremium que agregue características especiales.
Ventajas de la herencia:
Reutilización de código: Puedes usar y extender funcionalidades ya implementadas en la superclase.
Organización: Facilita estructurar jerarquías lógicas en tus clases.
Mantenibilidad: Si cambias algo en la superclase, las subclases pueden aprovechar los cambios automáticamente.
Ejemplo:
Dentro de la clase ClienteModel vamos a añadir un método nuevo que se va a encargar de mostrar la información de un cliente:
Ahora vamos a crear una nueva clase llamada ClientePremiumModel. Esta clase se va a encargar de manejar los clientes que sean premium (tienen descuentos). Al crear la clase usamos “extends” para que herede métodos y atributos de ClienteModel ya que tanto los clientes como los clientes premium son clientes.
En el constructor usamos super para llamar al constructor de nuestra clase ClienteModel:
Ahora si instanciamos un ClientePremium veremos que podemos usar los atributos y métodos como si fuera un Cliente normal y además usar también el atributo “descuento” que es único para ClientePremium.
Salida:
Nombre: Juan
Email: juan@gmail.com
Poliformismo
El polimorfismo es el tercer pilar de la POO. Significa "muchas formas" y permite que un mismo método se comporte de diferentes maneras según el objeto que lo llama.
Nos permite escribir código más flexible, ya que permite a diferentes clases responder de manera distinta a un mismo método. Esto es útil para manejar distintos tipos de objetos sin necesidad de muchas verificaciones if o switch.
Os voy a contar, desde mi experiencia, que no es una cosa que vayas a ver demasiado en los proyectos donde trabajes. No es demasiado utilizada pero es bueno que la conozcas y sepas cómo funciona.
Ejemplo
Te has podido dar cuenta de que de esta manera no podemos mostrar el descuento ya que el método “mostrarInformacion()” de Cliente no incluye nada para mostrarlo, ¿cómo lo hacemos?
Pues fácil. Creamos el método “mostrarInformacion()” también en ClientePremium y heredamos del método original usando super. También añadimos un nuevo “println” para mostrar el descuento:
Ahora si volvemos a instanciar el objeto veremos que por polimorfismo, Java es capaz de escoger el método mostrarInformación() de la subclase para mostrar la información con el descuento.
Salida final:
Nombre: Juan
Email: juan@gmail.com
Descuento: 20.0%
Y eso es todo por hoy, nos vemos en próximas clases.