Releases: CodeSystem2022/PowerBits-3erSemestre
Semana 13
PYTHON
Esta semana continuamos con el Pool de conexiones con Python y Postgresql.
El pool de conexiones permite mantener un conjunto de conexiones abiertas en espera, disponibles para ser reutilizadas.
En esta clase realizamos método para:
• Liberar conexiones
• Cerrar conexiones
Además creamos la Clase del Cursor del Pool y realizamos las pruebas necesarias para verificar que el proyecto funcione correctamente.
JAVA
Esta semana en el lenguaje de Java vimos la clase DAO.
La clase DAO actúa como un intermediario entre tu aplicación y la base de datos.
Proporciona métodos y operaciones que permiten realizar operaciones CRUD:
-CREAR, LEER, ACTUALIZAR, ELIMINAR
en la fuente de datos. De esta manera, los objetos de la aplicación no necesitan conocer los detalles de implementación de acceso a datos, lo que mejora la separación de responsabilidades y facilita el mantenimiento y la evolución del código.
SEMANA 12
JAVA
Procedemos a la instalación de MySQL y sus diferentes Querys. Creamos una base de datos desde una tabla. Después sincronizamos con Maven y agregamos su dependencia para poder seguir trabajando. Por ultimo creamos la clase conexión a MySQL usando la dependencia que utilizamos anteriormente.
Semana 11
PYTHON
En esta semana vimos lo que es el Pool de Conexiones con Postgresql
El pool de conexiones, sirve para administrar eficientemente las conexiones a una base de datos u otros recursos compartidos.
En resumen, el pool de conexiones es una técnica importante para optimizar el rendimiento y la eficiencia en el acceso a bases de datos u otros recursos compartidos. Proporciona un mecanismo de reutilización de conexiones, ahorra recursos, permite la escalabilidad y brinda control de concurrencia, todo lo cual contribuye a una mejor experiencia para los usuarios finales y una aplicación más robusta.
JAVASCRIPT
En la semana de Javascript continuamos con el proyecto Sistemas de Ventas
Creamos una clase llamada Producto y una clase llamada Orden y la clase de prueba VentasTest. La clase Producto y la clase Orden no se relacionan por herencia sino que por relación de agregación.
La relación de agregación se establece cuando una clase necesita utilizar los servicios o características de otra clase, pero no hay una dependencia fuerte entre ellas. Esto significa que la clase agregada puede existir independientemente de la clase agregadora. la relación de agregación en Python se logra pasando una instancia de una clase como argumento a otra clase, lo que permite que la clase agregadora utilice los servicios o características de la clase agregada.
JAVA
En esta se en Java comenzamos con el proyecto aplicación Listado de personas
La aplicación va a tener un menú que va a ser
ListadoPersonas:
1- Agregar
2- Listar
3- Salir
Trabajamos lo que es el encapsulamiento en todos los atributos, a través del atributo estático vamos contando los objetos. Como responsabilidades es la creación de objetos de tipo Persona en la clase idPersona.
Semana 10
PYTHON
En esta semana de python vimos la clase PersonaDAO.
Una clase DAO (Data Access Object) en Python es una clase diseñada para encapsular y gestionar el acceso a una fuente de datos, como una base de datos o una API. Su propósito principal es abstraer la lógica de acceso a los datos y proporcionar métodos para realizar operaciones CRUD:
- Seleccionar
- Insertar
- Actualizar
- Eliminar
La clase DAO actúa como una capa intermedia entre la aplicación y la base de datos. Esto facilita el mantenimiento y la flexibilidad de la aplicación, ya que cualquier cambio en la fuente de datos solo requiere modificar la clase DAO correspondiente, sin afectar el resto del código.
JAVA
En esta semana vimos un nuevo IDE, IntelliJ IDEA proporciona una amplia gama de características y herramientas que ayudan a los desarrolladores a escribir, depurar y mantener su código de manera más eficiente.
Lo que hicimos esta semana fue una calculadora con este nuevo IDE, aplicando conseptos dados en clase, tales como:
- ciclos while
- condicionales if - else
- switch - case
- try - catch
- metodos de clase
Todos esto junto y aplicado con logida de programacion, hizo posible la realizacion de la calculadora.
JAVASCRIPT
En esta semana vimos Herencia, que es un concepto fundamental de la programación orientada a objetos que permite la creación de nuevas clases basadas en clases existentes, aprovechando y extendiendo su funcionalidad.
Creamos dos clases hijas Empleado y Cliente, las cuales extendian de la clase Padre Persona, heredando asi sus atributos y metodos. Tambien aplicamos sobreescritura de metodos.
Semana 7
Java
En el lenguaje de Java vimos una nueva herramienta de trabajo llamada Docker:
Docker es una plataforma de código abierto que permite automatizar el despliegue, la ejecución y la administración de aplicaciones dentro de contenedores. Los contenedores son entornos ligeros y portátiles que encapsulan todas las dependencias y configuraciones necesarias para que una aplicación funcione correctamente.
¿Qué es un contenedor?
Un contenedor es una unidad ejecutable que incluye todo lo necesario para que una aplicación se ejecute de manera aislada en un entorno controlado. Contiene el código, las bibliotecas, las dependencias y las variables de entorno necesarias para que la aplicación funcione correctamente. Los contenedores son livianos, portátiles y pueden ejecutarse en cualquier sistema operativo que tenga Docker instalado.
Características principales de Docker:
-
Aislamiento: Los contenedores de Docker están aislados unos de otros y del sistema host, lo que garantiza que una aplicación en un contenedor no afecte a otras aplicaciones o al sistema operativo.
-
Portabilidad: Los contenedores de Docker son independientes del sistema operativo y de la infraestructura subyacente. Esto significa que un contenedor puede ejecutarse en cualquier entorno que tenga Docker instalado, lo que facilita la portabilidad de las aplicaciones.
-
Eficiencia: Los contenedores son livianos, ya que comparten el kernel del sistema operativo con el host y solo incluyen las bibliotecas y dependencias necesarias para la aplicación. Esto los hace más eficientes en términos de recursos y tiempo de ejecución.
-
Escalabilidad: Docker facilita la escalabilidad de las aplicaciones, ya que permite ejecutar múltiples contenedores de una misma aplicación de manera simultánea y distribuir la carga entre ellos.
Componentes principales de Docker:
-
Imágenes: Las imágenes son la base de los contenedores en Docker. Una imagen es un paquete autocontenido que incluye todo lo necesario para ejecutar una aplicación, como el código, las bibliotecas, las dependencias y las variables de entorno. Las imágenes se utilizan para crear contenedores.
-
Contenedores: Los contenedores son instancias en ejecución de una imagen. Un contenedor es un entorno aislado que contiene una aplicación y todas sus dependencias. Puede iniciarse, detenerse, reiniciarse y eliminarse fácilmente.
-
Dockerfile: Es un archivo de texto que contiene instrucciones para construir una imagen de Docker. El Dockerfile define cómo se crea una imagen a partir de una configuración específica, incluyendo el sistema operativo base, las dependencias, las variables de entorno, los comandos de instalación, etc.
-
Registro: Un registro de Docker es un repositorio centralizado donde se almacenan y se comparten imágenes de Docker. Docker Hub es el registro público más utilizado, pero también es posible utilizar registros privados para almacenar imágenes de forma segura.
Docker simplifica el proceso de implementación y administración de aplicaciones, ya que ofrece una forma estandarizada de empaquetar y distribuir aplicaciones con todas sus dependencias.
Python
Dentro de esta semana en el lenguaje Python trabajamos nuevamente en conjunto con la base de datos en Postgres.
Como primera parte empezamos con la corrección de errores. En PostgreSQL, los errores se conocen como "excepciones". Cuando ocurre un error durante la ejecución de una consulta o una transacción, PostgreSQL arroja una excepción junto con un mensaje de error descriptivo. Estos mensajes de error proporcionan información útil sobre qué salió mal y dónde ocurrió el problema.
Por otra parte, también vimos el manejo de transacciones en PostgreSQL, el cual se refiere a la capacidad del sistema para gestionar operaciones de bases de datos de manera consistente y confiable, garantizando la integridad de los datos incluso en situaciones de fallos o errores.
Una transacción es una secuencia de operaciones de bases de datos que se ejecutan como una unidad lógica e indivisible. Estas operaciones pueden incluir consultas de lectura (SELECT), modificaciones (INSERT, UPDATE, DELETE) u otras acciones que afecten a los datos almacenados en la base de datos.
JavaScript
Para lo que es el lenguaje de JavaScript trabajamos con lo siguiente:
Sintaxis de Clases en JavaScript
Las clases en JavaScript proporcionan una forma más estructurada y legible de trabajar con objetos y herencia en comparación con el enfoque basado en prototipos. Aunque JavaScript es un lenguaje basado en prototipos, las clases son una abstracción sintáctica que simplifica la creación y el manejo de objetos.
Esta sintaxis comienza con la palabra clave class, seguida del nombre de la clase en mayúscula. Por ejemplo: class Persona {...}. Dentro de la clase, se definen propiedades y métodos que describen el comportamiento y las características de los objetos que se crearán.
Se utiliza un constructor el cual es un método especial dentro de una clase que se llama automáticamente cuando se crea una nueva instancia de la clase utilizando la palabra clave new. El constructor se utiliza para inicializar las propiedades de los objetos y realizar tareas de configuración necesarias. Por ejemplo: constructor(nombre, apellido) {...}.
Dentro de la clase, se pueden definir propiedades utilizando el prefijo this, que se refiere al objeto actual. Por ejemplo: this.nombre = nombre; .
Método Get y Set
Los métodos get y set son funciones especiales que permiten acceder y modificar los valores de las propiedades de un objeto de manera controlada.
Los métodos get se utilizan para obtener el valor de una propiedad específica de un objeto. Estos métodos se definen utilizando la palabra clave get seguida del nombre de la propiedad. Por ejemplo: get nombre() {...}.
Por otra parte los métodos set se utilizan para asignar un valor a una propiedad específica de un objeto. Estos métodos se definen utilizando la palabra clave set seguida del nombre de la propiedad. Por ejemplo: set nombre(nuevoNombre) {...}.
Hoisting y Clases
Concepto de hoisting en JavaScript es un comportamiento que permite acceder a variables y funciones antes de que se declaren. En el caso de las clases, aunque la sintaxis de clase se declara en un lugar específico del código, las declaraciones de clase en sí se elevan o mueven al principio del ámbito actual.
A diferencia de las funciones, las clases no se pueden llamar antes de su declaración debido a su naturaleza y estructura. Solo el nombre de la clase puede ser utilizado antes de la declaración real de la clase, pero no se pueden crear instancias ni acceder a sus propiedades o métodos antes de la declaración.
Herencia
La herencia es un concepto fundamental en la programación orientada a objetos que permite crear jerarquías de objetos y compartir características y comportamientos comunes entre ellos. Una clase puede heredar propiedades y métodos de otra clase base, lo que fomenta la reutilización del código y la organización de las estructuras de objetos.
En JavaScript, la palabra clave extends se utiliza para establecer una relación de herencia entre una clase base y una subclase. La subclase hereda todas las propiedades y métodos de la clase base y puede agregar nuevos métodos o sobrescribir los existentes. Esto proporciona flexibilidad y la capacidad de personalizar el comportamiento de la subclase según sea necesario.
Dentro del constructor de una subclase, se utiliza el método super() para llamar al constructor de la clase base y asegurarse de que las propiedades de la clase base se inicialicen correctamente. Esto permite que la subclase herede y extienda el comportamiento de la clase base.
Semana 6
Python
En el lenguaje Python, esta semana vimos registros con PostgreSQL.
Los registros en PostgreSQL son estructuras de datos utilizadas para almacenar y organizar información de una manera tabular. Cada registro se compone de campos o columnas que representan diferentes atributos de los datos. Estos campos pueden contener diferentes tipos de datos, como números, texto, fechas, entre otros.
En Python, puedes interactuar con registros en PostgreSQL utilizando una biblioteca llamada "psycopg2". Esta biblioteca proporciona una interfaz para conectarte a una base de datos PostgreSQL y realizar operaciones como la creación de tablas, la inserción de datos y la consulta de registros.
Java
En Java, vimos la conversión de objetos; que se refiere al proceso de cambiar un objeto de un tipo a otro. Puede haber dos tipos de conversión:
• Conversión implícita (upcasting): Se produce cuando se asigna un objeto de una subclase a una variable de su superclase. Es seguro y no requiere una sintaxis especial, ya que la subclase es una extensión de la superclase.
• Conversión explícita (downcasting): Se produce cuando se asigna un objeto de una superclase a una variable de su subclase. Requiere una sintaxis especial mediante el operador de casteo (por ejemplo, Subclase sub = (Subclase) super;). El downcasting debe hacerse con cuidado y puede generar una excepción ClassCastException si el objeto no es compatible con la subclase.
JavaScript
En JavaScript, vimos algunas partes de los objetos.
Como, por ejemplo:
Métodos get y set: estos, son utilizados para acceder y modificar las propiedades de un objeto, respectivamente. El método get devuelve el valor de una propiedad, mientras que el método set asigna un nuevo valor a la propiedad. Estos métodos ayudan a controlar el acceso y la modificación de las propiedades de un objeto, proporcionando una interfaz consistente y segura para interactuar con ellas.
Constructores de objetos: estos, son funciones especiales utilizadas para crear nuevas instancias de una clase u objeto. Se definen utilizando la palabra clave “constructor” dentro de la declaración de una clase. Cuando se invoca un constructor utilizando la palabra clave “new”, se crea un nuevo objeto y se ejecuta el código dentro del constructor para inicializar sus propiedades y configurar su estado inicial.
Uso de call y apply: estos, son utilizados para invocar una función en un contexto específico. Permiten establecer el valor de “this” dentro de la función y pasar argumentos adicionales. La diferencia principal entre ellos es cómo se pasan los argumentos: “call()” acepta una lista de argumentos separados por coma, mientras que “apply()” acepta un arreglo de argumentos. Estos métodos son útiles para reutilizar funciones en diferentes contextos o para trabajar con funciones que esperan diferentes argumentos.
Semana 9
Python
En esta semana vimos lo que fue la creación de una nueva clase y logging
En Python, el logging es una técnica que se utiliza para registrar información sobre la ejecución de un programa. Es una forma de recopilar datos relevantes durante la ejecución de un programa y guardarlos en un archivo o imprimirlos en la consola para su posterior análisis.
El módulo de logging incluye varias clases y funciones que se utilizan para configurar y utilizar el registro en Python. Aquí hay una descripción básica de los componentes clave:
-
Logger: Es la clase principal del módulo de logging. Crea objetos Logger que se utilizan para registrar eventos. Puedes crear múltiples objetos Logger con diferentes nombres para registrar diferentes partes de tu programa.
-
Handler: Un objeto Handler define dónde se enviarán los registros. Puede enviar registros a la consola, a un archivo, a un socket de red, entre otros destinos. Puedes agregar varios controladores a un objeto Logger para que los registros se envíen a múltiples destinos.
-
Formatter: Define el formato en el que se mostrarán los registros. Puedes personalizar cómo se verá la información registrada, como la hora, el nivel de gravedad, el mensaje, etc.
-
Level: Los registros se pueden clasificar en diferentes niveles de gravedad, como DEBUG, INFO, WARNING, ERROR y CRITICAL. Puedes configurar el nivel de registro para filtrar los mensajes según su importancia. Por ejemplo, si estableces el nivel en WARNING, solo se registrarán los mensajes de advertencia, errores y excepciones.
Para utilizar el registro en Python, generalmente sigues estos pasos:
-
Importar el módulo de logging: import logging
-
Configurar la configuración de registro (opcional): Puedes personalizar el formato de los registros, establecer el nivel de gravedad y otros parámetros.
-
Crear un objeto Logger: logger = logging.getLogger('nombre_del_logger')
-
Configurar los controladores (handlers) y el formato (formatters): Puedes agregar uno o varios controladores y personalizar su formato.
-
Registrar eventos: Utiliza los métodos del objeto Logger, como logger.debug(), logger.info(), logger.warning(), logger.error(), etc., para registrar los eventos en diferentes niveles de gravedad.
Java
En java lo que estuvimos viendo fueron Excepciones
En Java, una excepción es un evento anómalo que ocurre durante la ejecución de un programa y que interrumpe el flujo normal de instrucciones. Cuando ocurre una excepción, se crea un objeto de una clase específica que representa esa excepción y se lanza (throw) para indicar que ha ocurrido un problema.
Las excepciones en Java se dividen en dos categorías principales: excepciones comprobadas (checked exceptions) y excepciones no comprobadas (unchecked exceptions).
-
Excepciones comprobadas: Son aquellas que el compilador obliga a manejar explícitamente en el código
-
Excepciones no comprobadas: Son aquellas que no requieren manejo explícito y no se verifican en tiempo de compilación.
Para manejar las excepciones en Java, se utilizan bloques try-catch. El bloque try contiene el código que puede lanzar una excepción, mientras que el bloque catch captura la excepción y ejecuta un código específico para manejarla. También se puede utilizar el bloque finally para ejecutar código que siempre debe ejecutarse, independientemente de si ocurre o no una excepción.
JavaScript
En JavaScript lo que vimos esta semana fue la palabra reservada static y sus usos
En JavaScript, la palabra clave static se utiliza en el contexto de las clases y los miembros de la clase. Tiene diferentes usos y efectos dependiendo de dónde se aplique:
- Métodos y propiedades estáticas de clase: Cuando se define un método o una propiedad estática en una clase, significa que están asociados directamente con la clase en sí misma, en lugar de con las instancias individuales de esa clase. Esto significa que se pueden acceder al método o a la propiedad estática sin necesidad de crear una instancia de la clase. Se accede a ellos a través del nombre de la clase seguido de un punto.
- Propiedades estáticas de objeto: Además de los métodos estáticos, también se pueden definir propiedades estáticas en una clase. Al igual que los métodos estáticos, estas propiedades están asociadas directamente con la clase y no con las instancias individuales.
En resumen, en JavaScript, la palabra clave static se utiliza para declarar métodos y propiedades estáticas en una clase. Estos miembros están asociados directamente con la clase en sí misma y se pueden acceder sin crear una instancia de la clase.
SEMANA 4
PYTHON
Esta semana vemos la instalación de "Postgresql" en windows, investigamos la instalación en otros sistemas.
Postgresql es un sistema de código abierto de administración de bases de datos del tipo relacional.
Creamos una base de datos llamada prueba_bd y cargamos una tabla con tus respectivas columnas, después consultamos con código Query en Postgresql.
Query es un lenguaje especifico de dominio, diseñado para administrar y recuperar informacion de sistemas de gestion de bases de datos relacionales.
Después procedemos a la instalación del módulo Postgresql en PyCharm, hacemos la conexión hacia la base de datos en Python con el método fetchall().
Usamos el siguiente código para hacer la conexión:
resultados = cursor.fetchall()
for registro in resultados:
print (registro)
JAVASCRIPT
En esta semana empezamos a trabajar con programación orientada a OBJETOS.
La diferencia entre un tipo primitivo como puede ser de un tipo numérico y un objeto es que el tipo primitivo no contiene propiedades ni tampoco métodos caso contrario a objetos que si los tiene.
Ejemplo:
Variable de tipo primitivo
let x = 10
console.log(x.lenght); "undefined"
_Objeto_
let persona = {
nombre: 'Carlos' ,
apellido: 'Gil' ,
email: 'cgil@gmail.com' ,
edad: 30
}
console.log(persona.nombre);
Agregamos métodos a los objetos es decir que veremos como se agregará un método para imprimir en este caso el nombre completo, se concatenará el nombre y el apellido que se encuentran ubicados dentro del bloque de código realizado; cuando agregamos un método estamos agregando una propiedad, ya que ambas son equivalentes. Para acceder a las propiedades, atributos, se utiliza el operador "this" que es un apuntador del objeto que se está trabajando.
Con lo que es la creación de métodos se ve la creación de objetos en JavaScript. Vemos también la forma de crear objetos a través de la palabra reservada "new".
Trabajamos cómo es acceder a las propiedades de los objetos. Accedimos a los objetos como si fueran un arreglo, nos sirve para recorrer todas las propiedades de nuestro objetos usando un ciclo "for"
JAVA
Esta semana empezamos a trabajar con el método "forEach" el cual nos ayuda las formas en que recorremos los arreglos o correcciones.
Procedemos a trabajar con Autoboxing y Unboxing que son de tipo primitivo.
Vemos los diferentes tipos de modificadores de acceso public modificadores de acceso protected, modificadores de acceso default o package y modificador de acceso private.
Semana 8
Java
En el lenguaje de Java esta semana vimos manejo de interfaces:
Una interfaz es una colección de métodos abstractos y constantes (variables estáticas finales).
¿Para que se utilizan?
Se utilizan para definir un contrato o un conjunto de comportamientos que una clase debe implementar. Es una herramienta clave para lograr la abstracción y la modularidad en la programación orientada a objetos.
¿Qué nos permiten?
Las interfaces permiten definir contratos claros entre componentes y facilitan la interoperabilidad entre diferentes clases y componentes de un programa.
Por ejemplo:
// Definición de la interfaz
public interface Calculadora {
int sumar(int a, int b);
int restar(int a, int b);
}
// Implementación de la interfaz en una clase concreta
public class CalculadoraBasica implements Calculadora {
@OverRide
public int sumar(int a, int b) {
return a + b;
}
@Override
public int restar(int a, int b) {
return a - b;
}
}
// Uso de la interfaz y la implementación
public class Main {
public static void main(String[] args) {
Calculadora calculadora = new CalculadoraBasica();
int resultadoSuma = calculadora.sumar(5, 3);
System.out.println("Suma: " + resultadoSuma); // Resultado: 8
int resultadoResta = calculadora.restar(7, 2);
System.out.println("Resta: " + resultadoResta); // Resultado: 5
}
}
Python
Dentro de esta semana en el lenguaje Python vimos Logging y continuamos con Postgresql:
Empezamos creando un diagrama UML, dentro del mismo se crea una capa de datos, como también, creamos una clase que administra la conexión hacia la base datos y definimos atributos estáticos.
Manejo de registros (logging)
El mismo proporciona una forma flexible y configurable de generar registros de información, advertencias, errores y otros mensajes relevantes durante la ejecución de un programa.
Ejemplo:
import logging
Configurar la configuración básica del logging
logging.basicConfig(level=logging.DEBUG,
format='%(asctime)s - %(levelname)s - %(message)s')
Ejemplos de registro
logging.debug('Este es un mensaje de depuración')
logging.info('Esta es una información')
logging.warning('¡Cuidado! Esto es una advertencia')
logging.error('Se produjo un error')
logging.critical('Esto es crítico')
El módulo logging de Python es muy versátil y permite un control completo sobre el manejo de registros en tus programas.
JavaScript
Para lo que es el lenguaje de JavaScript en esta semana continuamos lo que quedó pendiente en la clase anterior.
Semana 5
Java
En el lenguaje de java esta semana vimos: Sobreescritura, Polimorfismo y instanceof.
¿Qué es sobreescritura?
La sobreescritura de métodos, también conocida como "overriding", es un concepto que permite a una clase hija proporcionar una implementación específica de un método que ya está definido en su clase padre.
Cuando una clase hija hereda de una clase padre, puede utilizar los métodos de la clase padre. Sin embargo, en algunos casos, la clase hija puede querer modificar o extender el comportamiento de un método específico heredado de la clase padre. Ahí es donde entra en juego la sobreescritura de métodos.
¿Cómo utilizar la sobreescritura de métodos en Java?
Para utilizar la sobreescritura de métodos, sigue estos pasos:
-
Define una clase padre: Crea una clase que contenga el método que deseas sobrescribir. Esta clase será la clase padre.
-
Define una clase hija: Crea una nueva clase que herede de la clase padre utilizando la palabra clave extends. La clase hija contendrá la implementación personalizada del método que se va a sobrescribir.
-
Sobrescribe el método: En la clase hija, declara un método con la misma firma (nombre y parámetros) que el método en la clase padre. Utiliza la anotación @OverRide opcionalmente para asegurarte de que estás sobrescribiendo correctamente el método. Dentro del método, proporciona la implementación específica que deseas.
-
Utiliza la clase hija: Crea instancias de la clase hija y llama al método sobrescrito. La implementación específica de la clase hija se ejecutará en lugar de la implementación del método en la clase padre.
La sobreescritura de métodos es una característica importante de la programación orientada a objetos, ya que permite el polimorfismo y la especialización de comportamiento en las clases hijas.
Polimorfismo:
El polimorfismo es un concepto fundamental de la programación orientada a objetos que autoriza a un objeto a comportarse de diferentes maneras dependiendo del contexto en el que se utilice. El polimorfismo se basa en dos características claves: herencia y sobreescritura de métodos.
¿Qué nos permite?
El polimorfismo permite tratar a un objeto de una clase hija como si fuera un objeto de su clase padre.
¿Por qué es útil?
El polimorfismo es útil porque permite escribir código más genérico y flexible. En lugar de depender de implementaciones específicas de clases hijas, se puede trabajar con objetos de la clase padre y confiar en que el comportamiento correcto será invocado automáticamente, dependiendo del tipo real del objeto en tiempo de ejecución.
Operador instance of:
¿Para que se utiliza?
En Java, el operador instanceof se utiliza para comprobar la relación de herencia entre clases y no puede usarse para verificar si un objeto es una instancia de una interfaz o una clase abstracta.
El operador instanceof devuelve un valor booleano (true o false) que indica si el objeto es una instancia de la clase especificada o de una subclase de esa clase.
¿Cuándo es útil?
instanceof es útil cuando se desea verificar el tipo de un objeto antes de realizar operaciones específicas basadas en ese tipo. Esto puede ser útil, por ejemplo, para tomar decisiones de control de flujo o para realizar castings seguros (casting condicional) en tiempo de ejecución.