Mostrando las entradas con la etiqueta Lenguaje de Programación. Mostrar todas las entradas
Mostrando las entradas con la etiqueta Lenguaje de Programación. Mostrar todas las entradas

6 de julio de 2017

Excepciones.

   El lenguaje de programación Java utiliza excepciones para manejar errores y otros eventos excepcionales. Un programa en Java puede utilizar excepciones para indicar que ha ocurrido un evento excepcional, de hecho, el término excepción es la forma corta de decir evento excepcional.

   En este sentido, una excepción es un evento que ocurre durante la ejecución de un programa en Java, que interrumpe el flujo normal de ejecución del programa (vea What is an Exception).

   Cuando un error ocurre dentro de un método, el método crea un objeto (objeto de excepción) y lo coloca en el entorno de ejecución, el cual contiene información acerca del error, incluyendo su tipo y el estado del programa cuando ocurrió el error. A éste proceso se le denomina lanzar una excepción.

   Después de que un método lanza una excepción el entorno de ejecución intenta encontrar a alguien (manejador de excepción) que la atrape y la maneje:

La pila de invocación de métodos y la búsqueda del manejador de excepción (adaptada de What is an Exception).

   Para lanzar un excepción se debe hacer uso de la cláusula throw adjunta a un objeto de excepción (descendiente de la clase Throwable) para proporcionar información específica acerca del evento excepcional que ocurrió.

   Un código válido en el lenguaje de programación Java debe respetar la cláusula catch (también llamado requisito de especificación), lo cual significa que el código que podría lanzar ciertas excepciones debe estar encerrado por alguna de las siguientes:
  • Una sentencia try que atrapa la excepción.
  • Un método que especifica que puede lanzar la excepción.
  Cabe mencionar que no todas las excepciones están sujetas a esta situación, y la razón es que existen tres categorías básicas de excepciones y sólo una de ellas está sujeta a dicho requisito (excepción comprobada):
  1. Excepción comprobada (checked exception): condiciones excepcionales que un programa o aplicación bien escrita debe considerar.
  2. Error: condiciones excepcionales que son externas al programa o la aplicación; usualmente no es posible anticiparlas o recuperarse de ellas (mal funcionamiento del hardware o del sistema).
  3. Excepción en tiempo de ejecución (runtime exception): condiciones excepcionales que son internas al programa o la aplicación sin que la aplicación pueda anticiparlas o recuperarse de ellas (errores lógicos a bugs).
   Las excepciones de error y de tiempo de ejecución se conocen comúnmente como excepciones no comprobadas o verificadas (unchecked exceptions).

   Un programa puede atrapar excepciones por medio de la combinación de los bloques try, catch y finally:
  1. El bloque try identifica un bloque de código en el que una excepción puede ocurrir.
  2. El bloque catch identifica un bloque de código, conocido como manejador de excepción (exception handler), que puede atrapar y manejar un tipo específico de excepción.
  3. El bloque finally identifica un bloque de código que en general se garantiza que se ejecutará independientemente de si se generó (catch) o no (try) la excepción, por lo que es el lugar preciso para cerrar archivos, liberar recursos y cualquier tarea de limpieza que se requiera como parte de la ejecución del código que se ejecutó en el try.

   Una cláusula try podría contener al menos un bloque catch o finally, y múltiples bloques catch.

    Como un primer acercamiento, considere inicialmente el Ejemplo DivisionSinManejoExcepcion el cual muestra la posible generación de una excepción no verificada (unchecked) si se intenta hacer una división por cero (línea 16). La excepción que podría generarse es de la clase ArithmeticException; pero todavía más: ¿Qué sucede si en lugar de un número se introduce una letra o una cadena? Se conmina al lector a probar lo hasta aquí expuesto.

    El Ejemplo DivisionConManejoExepcion toma ya en consideración lo expuesto en el párrafo anterior e ilustra el uso de la cláusula try-catch líneas (27-43). El manejo de excepciones consiste en hacer que un programa, ante una situación anormal o fuera del flujo esperado de ejecución, pueda recuperarse y continuar y no simplemente terminar. Note que con excepción de las cláusula en cuestión, el programa es esencialmente el mismo que el anterior, con la consideración del ajuste de una bandera para determinar o no la continuación del programa (líneas 24, 35 y 44). Este ejemplo, además del manejo de la excepción aritmética, también considera la excepción InputMismatchException para el caso de que no se proporcionen los números enteros como entrada sino alguna otra cosa.

    ¿En qué orden debería colocarse las excepciones?, ¿cuál debemos poner primero? Las recomendaciones, una vez que se asume que se han localizado las excepciones más pertinentes, serían dos:

  1. Atrape primero la excepción que a su consideración tenga más probabilidad de ocurrir, después la segunda y así sucesivamente.
  2. Coloque primero las excepciones más específicas y al final las más generales; para ello, deberá consultar la jerarquía de clases correspondiente.

   Finalmente, además de invitar al lector a revisar el API de Java para la revisión y familiarización de las excepciones comentadas en esta entrada, es importante resaltar que la decisión de utilizar excepciones propias comprobadas (checked) o no (unchecked) debería seguir esta guía: si un cliente o usuario de nuestras clases tiene una expectativa de recuperarse razonablemente de una excepción, entonces la excepción debería ser del tipo comprobada (checked); por otro lado, si no puede hacerse nada para recuperarse de la excepción ésta debería ser no comprobada (unchecked). Para más información vea Unchecked Exceptions - The controversy.


5 de abril de 2017

Algunas aplicaciones (pilas).

    A continuación se presentan algunas de las aplicaciones más representativas de una pila, cabe mencionar que esta selección es necesariamente incompleta.

Análisis básico de expresiones.
   Considere la siguiente expresión:


   Se insta al lector a que sea tan amable de contestar una por una, las siguientes preguntas:
  • ¿Es clara?, es decir, ¿se entiende?
  • Para valores concretos de x, y, y j, ¿podría evaluarla?
  • ¿Puede escribir la misma expresión en una sola línea de texto, como lo haría para un programa?
   La representación "lineal" de la expresión anterior se muestra a continuación:

7 – ( (x * ( (x + y) / (j - 3) ) + y) / (4 – 5/2) )

   Observe que la expresión anterior contiene paréntesis, los cuales son indispensables para agrupar de manera apropiada las operaciones involucradas, mientras que la primera representación no los tiene, ya que son innecesarios. Ahora bien, en base a lo anterior considere lo siguiente:
  • ¿Cómo saber que la expresión lineal está correctamente balanceada en cuanto a paréntesis se refiere, de tal forma que represente exactamente lo mismo que la expresión original?
  • ¿Y si la expresión original fuera más grande y/o más compleja?
   Considere ahora esta otra expresión:


   Cuya representación “lineal” está dada por:

{x + (y – [a + b]) * c – [ (d + e) ] } / (h – (j – (k – [l - n] ) ) )

   Al igual que antes:
  • ¿Cómo saber si la expresión lineal está correctamente balanceada en cuanto a símbolos de agrupación se refiere? Note que ahora se han introducido otros símbolos de agrupación de expresiones (corchetes y llaves) además de los paréntesis.
  • Adicionalmente, ¿cómo saber que un símbolo de agrupación está cerrando a su correspondiente símbolo de apertura?, es decir, ¿cómo saber que los símbolos de agrupación están correctamente asociados?
   Debería resultar claro que es mucho más fácil para las personas comprender expresiones denotadas como en las expresiones originales; sin embargo, las representaciones "lineales" son las que se utilizan en los lenguajes de programación, por lo que se requiere de un mecanismo que verifique de manera automática que una expresión esté bien escrita, al menos en cuanto a símbolos de agrupación se refiere; para ello, considere el siguiente Algoritmo de verificación de balanceo:

   valida = true;
   p = pila vacía;

   while( no sea fin de cadena y la expresion sea válida ){
      procesar el siguiente símbolo de la cadena;

      if ( símbolo == ‘(’ | | símbolo == ‘[’ | | símbolo == ‘{’ )
         p.push(símbolo);
      else if ( símbolo == ‘)’ | | símbolo == ‘]’ | | símbolo == ‘}’ ){
         if ( p.estaVacia( ) )
            valida = false;
         else{
            char s = p.pop( );
            if ( s no es equivalente a símbolo )
               valida = false;
         }
      }
   }  // while

   if ( !p.estaVacia( ) )
      valida = false;
 
   if ( valida )
      println("La expresión es correcta y está balanceada.”);
   else
      println("Existe error en los símbolos de agrupación.”);

Algoritmo de verificación de balanceo.

   Dada una expresión almacenada en una cadena, el Algoritmo de verificación de balanceo utiliza una pila para realizar la verificación de los símbolos de agrupación que se encuentren en dicha expresión.

   Se deja como ejercicio para el lector realizar una implementación de dicho algoritmo, así como la resolución de los aspectos inherentes a la equivalencia de símbolos (vea el Ejercicio 9 de la entrada Ejercicios selectos para pilas Java y C++ respectivamente).

   Notación interfija, postfija y prefija.
   Considere la suma de dos números cualesquiera A y B. Aplicar el operador “+” a los operandos A y B y representar la suma como A + B tiene el nombre de representación o notación interfija.

   La notación interfija, aunque es la más común, no es la única. Existen al menos otras dos notaciones alternativas para expresar la suma de A y B utilizando los mismos símbolos A, B y +:
  1. + A B representación o notación prefija.
  2. A B + representación o notación postfija.
   Los prefijos “pre”, “pos” e “inter” hacen referencia a la posición relativa del operador en relación a los operandos.

   El llamado o invocación a una función en un lenguaje de programación gobernado por el paradigma estructurado, como el lenguaje C por ejemplo, utiliza notación prefija (considere por ejemplo la suma de dos números enviados a una función invocada mediante suma(a, b)), ya que el operador (suma) precede a los operandos (a, b).

   Conversión de interfija a postfija.
   Considere la siguiente expresión:

A + B x C

la cual implícitamente indica:

A + (B x C)

   Suponga que se desea convertir la expresión anterior a su representación en postfija ¿Cómo proceder?

   Los ejemplos siguientes asumen una representación "lineal" de las expresiones. En base a lo anterior, es importante que el lector tenga presente que el proceso de conversión se basa en las reglas de precedencia de los operadores involucrados en la expresión a convertir.

   Así, para convertir una expresión de su notación interfija a su notación postfija, se tienen lo siguientes pasos:
  1. A + (B x C)     forma interfija.
  2. A + (BC x)    se convierte la multiplicación y el nuevo elemento se considera como un solo número (de hecho, después de aplicar el operador el resultado (producto) es en efecto, otro número).
  3. A (BC x) +    se convierte la suma con las mismas consideraciones expuestas en el punto anterior.
  4. A B C x +     se eliminan paréntesis para obtener la representación final en postfija.
   Con base en lo anterior, es posible afirmar que las dos reglas que se siguen durante el proceso de conversión a postfija son las siguientes:
  1. Las operaciones con mayor precedencia se convierten primero. Si existe más de una operación con la misma precedencia, se resolverá primero la que esté más a la izquierda.
  2. Después de que una parte de la expresión se ha convertido a notación postfija, ésta se considerará como un operando único.
   Ejemplo:
   Dada la siguiente expresión (note que no es la misma que la expresión anterior):

(A + B) x C

convierta dicha expresión a su notación postfija.

   En base a lo expuesto con anterioridad, el proceso de solución está dado por los siguientes pasos:
  1. (A + B) x C    forma interfija.
  2. (A B +) x C    se convierte la adición.
  3. (A B +) C x    se convierte la multiplicación.
  4. A B + C x       se eliminan paréntesis: representación postfija.
   Conversión de interfija a prefija.
   Las reglas para convertir una expresión de su notación interfija a su notación prefija son idénticas a las de conversión de interfija a postfija. El único cambio a considerar es que ahora el operador se coloca antes de los operandos en lugar de colocarlo después de ellos.
 
   Aspectos a considerar.
Finalmente, respecto a las notaciones prefija y postfija cabe hacer mención de un par de consideraciones:
  1. La representación prefija no siempre es una imagen reflejo de la representación postfija.
  2. El orden de los operadores en las expresiones postfijas determina el orden real de las operaciones al evaluar la expresión, haciendo en consecuencia innecesario el uso de paréntesis.
   En la entrada correspondiente a los Ejercicios selectos para pilas Java y C++ respectivamente tendrá la oportunidad de practicar y de ampliar su experiencia al respecto.

   Evaluación de expresiones.
   Aunque para las personas en general es más fácil y natural comprender las expresiones interfijas (quizá porque en su mayoría así fuimos instruidos y así estamos acostumbrados pero, ¿qué pasaría si desde pequeños, en lugar de haber aprendido a realizar operaciones utilizando notación interfija, se nos hubiera enseñado a realizarlas utilizando notación prefija por ejemplo? ¿Qué sería entonces lo fácil y natural de comprender?), el procesamiento de dichas expresiones por medio de una computadora no es nada sencillo.

   Considere lo siguiente: dada una expresión en notación interfija con valores específicos ¿Cómo evaluaría algorítmicamente dicha expresión? Piense y reflexione en ello antes de continuar.

   Ahora bien, con valores específicos para una expresión en notación postfija ¿Cómo evaluaría algorítmicamente dicha expresión? Para esto último, considere el siguiente Algoritmo de evaluación de una expresión en notación postfija:

         pilaOperandos = pila vacía;

         while(no sea fin de cadena){

             símbolo = siguiente carácter de la cadena;
             if(símbolo es un operando)
                   pilaOperandos.push(símbolo);
             else{
                   numero2 = pilaOperandos.pop( );
                   numero1 = pilaOperandos.pop( );
                   resultado = numero1 símbolo numero2;
                   pilaOperandos.push(resultado);
             }
         }
         return pilaOperandos.pop();

Algoritmo de evaluación de una expresión en notación postfija.

   La solución propuesta por el Algoritmo de evaluación de una expresión en notación postfija se basa, como es de esperarse, en una pila. Se deja como ejercicio al lector el análisis y comprensión de dicho algoritmo, así como su correspondiente implementación (consulte la entrada correspondiente a Ejercicios selectos para pilas Java y C++ respectivamente para obtener mayor información).

6 de marzo de 2017

Ejercicios selectos (transición).

  1. Investigue más acerca del concepto de máquina virtual y de los bytecodes ¿Fue Java el primer lenguaje de programación en incorporar dichos conceptos?
  2. Para el programa del Ejemplo Bienvenido2 pruebe lo que sucede si elimina el espacio que aparece al final de la cadena Bienvenid@. No olvide volver a compilar.
  3. Considere el Ejemplo Bienvenido3 e investigue qué otras secuencias de escape existen, también infórmese si dichas secuencias coinciden o no con las que se utilizan en el lenguaje de programación C.
  4. En base a lo expuesto para el Ejemplo Bienvenido4 investigue qué otros especificadores de formato existen. Infórmese también si dichos especificadores coinciden o no con los que se utilizan en el lenguaje de programación C.
  5. Escriba un programa que imprima en la salida estándar su nombre (el nombre del lector). El nombre o nombres deberá aparecer en el primer renglón, el primer apellido en el segundo renglón y el segundo apellido en el tercer renglón.
  6. Utilice el Ejemplo Lectura y cambie la clase Integer por el tipo primitivo int. Compruebe si es necesario o no hacer algún otro tipo de cambio para que el programa funcione.
  7. En base a lo descrito en el Ejemplo Lectura modifique dicho ejemplo para agregar las cuatro operaciones aritméticas: suma, resta multiplicación y división. Los operadores aritméticos son los tradicionales: +, -, * y /. Realice lo anterior para números enteros representados como objetos (Integer), y como tipos de datos primitivos.
  8. Modifique el Ejemplo Lectura para procesar ahora números Float y Double. Tome en cuenta que deberá consultar el API para cambiar el método nextInt por el método apropiado. Investigue también si existen los tipos de datos primitivos correspondientes (float y double).
  9. Con base en lo descrito en el Ejemplo Lectura, modifique dicho ejemplo para que solicite al usuario su nombre completo. Tome en cuenta que deberá leer tres cadenas como se describe a continuación, y que su programa deberá imprimir el nombre completo por apellidos en una sola línea:
    1. Su nombre o nombres.
    2. Su primer apellido.
    3. Su segundo apellido

 10. Para el Ejemplo If, ¿qué sucede si cambia la estructura de selección if por if-else? ¿Se obtiene el mismo funcionamiento? Si cambia el funcionamiento, ¿por qué? Determine su respuesta y después corroborela haciendo los cambios correspondientes. No olvide volver a compilar.

 11. Escriba un programa que presente un menú con las cuatro operaciones aritméticas y una opción para salir. Su programa deberá procesar la opción y realizar la operación correspondiente, así como mantenerse repitiendo el menú hasta que se proporcione la opción de "Salir". Investigue también si el lenguaje Java incorpora una estructura de selección múltiple (switch) como la del lenguaje C. Para este ejercicio, basta con utilizar una estructura if-else anidada. El menú deberá ser como se describe a continuación:

  • Suma.
  • Resta.
  • Multiplicación.
  • División
  • Salir.

 12. Modifique el Ejemplo Arreglo para que, utilizando el procesamiento de argumentos en la línea de comandos como el que se hizo en el Ejemplo MainArgs acepte tres argumentos. Su programa deberá generar un arreglo de n enteros con un valor inicial para el primer elemento y un incremento para los demás. Observe que los elementos de args son cadenas, por lo que tendrá que consultar el API para utilizar métodos de conversión de cadenas a números enteros.

Sugerencia: consulte el método parseInt de la clase Integer. Los argumentos a procesar en la línea de comandos son:

  • Tamaño del arreglo (n).
  • Valor inicial (valor).
  • Incremento (incremento).

 13. Siguiendo la idea del ejercicio anterior, escriba un programa que procese el tamaño (n) de un arreglo desde la línea de comandos y:

  • Genere un arreglo de enteros de tamaño n.
  • Solicite y almacene n enteros en el arreglo.
  • Determine, haciendo un recorrido del arreglo, el número mayor.
  • Determine, haciendo un recorrido del arreglo, el número menor.
  • Determine, haciendo un recorrido del arreglo, el promedio (media aritmética).
  • Determine, haciendo un recorrido del arreglo, la moda (el número que más veces aparece).
  • Determine, haciendo un recorrido del arreglo, si un número determinado está o no en el arreglo (búsqueda lineal).

 14. Consulte al menos la entrada Excepciones para introducirse en el tema y ampliar un poco más su conocimiento respecto al uso y manejo básico de excepciones en Java.
 15. Considere el Ejemplo Coleccion. Investigue en el API las colecciones, particularmente la colección ArrayList y determine el funcionamiento del programa antes de compilarlo y ejecutarlo en la máquina virtual de Java. Compruebe su deducción respecto al funcionamiento con la salida real del programa. 


3 de marzo de 2017

Estructuras de datos (tipos de datos y referencias).

   Probablemente el lector esté familiarizado con el concepto de tipo de dato, ya sea debido a que tenga experiencia previa con algún lenguaje de programación, o simplemente porque ha revisado la entradas correspondientes a Un vistazo a Java (Un vistazo a C++) o las relacionadas a los conceptos de la Programación Orientada a Objetos. En este sentido valdría la pena preguntarse ¿cómo se podría definir lo qué es un tipo de dato?

   Un tipo de dato es un método para interpretar un patrón de bits. Una secuencia de bits determinada podría ser interpretada de una forma u otra y representar algún tipo de información específica en función del tipo de dato.

   En la mayoría de los lenguajes de programación, el programador especifica mediante las declaraciones de variables u objetos, cómo es que el programa va a interpretar el contenido de la memoria de la computadora.

   Las declaraciones también le especifican al compilador exactamente, qué es lo que representan los símbolos de las operaciones que se utilizarán, ya que aunque en apariencia es lo mismo, los mecanismos de implementación de una operación aritmética tan aparentemente simple como la adición, difieren de un tipo de dato a otro.

   Por otro lado, para la mayoría de los lenguajes de programación los nombres de las variables o los identificadores asociados a los objetos, son en realidad referencias, es decir, direcciones de memoria en las que se almacenan físicamente los objetos a los que se refieren.

   El manejo de referencias o direcciones de memoria puede ser explícito como en el caso de los lenguajes C y C++ por ejemplo, donde el manejo de referencias se realiza a través de apuntadores. En algunos otros lenguajes como Java y C# el manejo de referencias es implícito, es decir, se realiza a través del nombre o identificador de los objetos.
 
   Tanto el manejo de referencias explícito como el implícito tienen sus ventajas y desventajas, y las fortalezas de uno son las debilidades del otro y viceversa. No es la intención de esta entrada ni la del blog extenderse en dichos aspectos, ya que para los objetivos específicos que se persiguen, basta con saber que Java hace uso de referencias implícitas, y que el nombre o identificador de los objetos es en realidad una referencia y no los objetos en sí mismos. Por otro lado, C++ utiliza tanto referencias implícitas como explícitas.

   En entradas y secciones posteriores se detallarán y ejemplificarán tanto el concepto de autorreferencia como el manejo de referencias para los objetos, elementos que serán indispensables para la construcción y manipulación de las estructuras de datos que se implementarán.



13 de febrero de 2017

Programación orientada a objetos.

   En entradas anteriores se discurrió en los elementos fundamentales de la orientación a objetos:
   La intención de dichas entradas es la de proporcionar al lector un panorama general del paradigma orientado a objetos sin asociarlo necesariamente con la programación, y mucho menos con algún lenguaje de programación en particular.

   Un lenguaje de programación es sólo un medio para el paradigma, no el paradigma en sí. Por otro lado, el ejercicio o labor de la programación es la forma de aplicar los conceptos asociados al paradigma.

   Las entradas subsecuentes irán detallando al lector los conceptos presentados pero desde la perspectiva de la programación y su aplicación en algún lenguaje de programación. Sin embargo, es importante aclarar que el objetivo del blog no es enseñar los lenguajes de programación, sino el de utilizarlos como un medio para hacer tangibles los conceptos de orientación a objetos.

   El blog proporciona entradas particulares que introducen a algunos de los aspectos de los lenguajes de programación Java y C++ que podrían ser de utilidad para el lector, pero de ninguna manera pretende cubrir los elementos completos de dichos lenguajes, sino solamente presentar un panorama general:
   Además de lo anterior el blog presenta las bases del paradigma orientado a objetos en el contexto de su aplicación a la programación utilizando al lenguaje de programación Java y C++.

   La intención principal de las entradas que siguen este enfoque que se acaba de mencionar, es la de concretizar en algún lenguaje de programación los conceptos más distintivos del paradigma orientado a objetos, para que en entradas posteriores se puedan aplicar al desarrollo de las estructuras de datos, y mejorar así tanto la comprensión de los conceptos, como la experiencia del lector.


10 de febrero de 2017

Ejercicios selectos (Orientación a objetos).

  1. Investigue más acerca de la historia y desarrollo de la programación orientada a objetos.
  2. Xerox es actualmente una compañía que desarrolla equipo de foto copiado e impresión entre otras cosas. Investigue cuál era el sistema operativo que utilizaban en los años de Xerox PARC (Palo Alto-California Research Center) que por cierto, ya incluía una GUI (Interfaz Gráfica de Usuario) pionera de las GUI que actualmente se utilizan.
  3. Investigue la historia y la ideología del lenguaje de programación Smalltalk. Aproveche para conocer el nombre de su(s) creador(es).
  4. Investigue la historia y la ideología del lenguaje de programación Eiffel. Aproveche para conocer el nombre de su(s) creador(es).
  5. Investigue la historia del lenguaje de programación C++. Aproveche para conocer el nombre de su(s) creador(es).
  6. Investigue el papel del Dr. Alan Curtis Kay en la concepción y desarrollo de la programación orientada a objetos.
  7. Investigue qué otros paradigmas de programación existen.
  8. Investigue qué lenguajes de programación actuales soportan el paradigma orientado a objetos, cuáles lo soportan de manera nativa y cuáles como una extensión.


27 de enero de 2017

A modo de prefacio.

   Estimado lector, este blog tiene una orientación específica. Está pensado como un curso introductorio de programación orientada a objetos en donde, de manera preferente aunque de ninguna manera obligatoria, se haya tenido un contacto previo con algún lenguaje de programación utilizando el enfoque estructurado; sin embargo, también es mi intención que el blog sea de utilidad para aquellos lectores que se quieran iniciar en el mundo de la programación y el paradigma orientado a objetos sin ningún requisito previo de programación.

   El blog asume que el lector posee conocimientos básicos de algoritmos y/o programación, así como el funcionamiento de las estructuras de control secuencial, de selección, y de repetición. Por otro lado, si bien es cierto que para la comprensión del paradigma no son precisos dichos conocimientos (de hecho podrían generar un vicio para un paradigma de programación orientado a objetos más puro), sí lo son para la comprensión y el seguimiento correspondiente de los programas de ejemplo.

   Con todo, el blog proporciona una entrada para apoyar al lector a través de ejemplos selectos tanto en la introducción del lenguaje de programación utilizado, como en los conceptos fundamentales de la programación.

   Existe desde hace mucho tiempo un debate acerca de si es mejor enseñar el paradigma orientado a objetos sin antes tener un conocimiento de otro enfoque de programación (como el estructurado por ejemplo), o si es mejor partir de la programación estructurada para realizar una transición hacia la programación orientada a objetos. En mi opinión ambos enfoques tienen sus ventajas y desventajas.

   Java es un lenguaje de programación híbrido, en el sentido de que no es un lenguaje totalmente orientado a objetos como Smalltalk, y en ese sentido, tiene estructuras de control y tipos de datos primitivos al estilo del lenguaje de programación C, el cual es el lenguaje por antonomasia para la programación estructurada y, dado que este blog utiliza a Java y C++ como lenguajes de programación, aquellos lectores que conozcan el lenguaje C se sentirán familiarizados rápidamente con Java (e indudablemente con C++) concentrándose entonces en la asimilación del paradigma y en su aplicación.

   Por otro lado, aquellos lectores que no conozcan el enfoque estructurado estarían, al menos de primera instancia, sin la predisposición a cometer uno de los vicios más comunes al programar en el enfoque orientado a objetos, como lo es el de utilizar un lenguaje de programación orientado a objetos, para escribir programas en un enfoque estructurado. En éste sentido, resulta fundamental enfatizar desde ahora que el uso de un lenguaje de programación orientado a objetos no hace per se, ni mucho menos garantiza, que los programas que se escriban en dicho lenguaje sigan el modelo de programación orientado a objetos.

   Como en muchas cosas de la vida y lo cotidiano, más que establecer qué es lo mejor y qué no lo es, ya que se está ante una disyuntiva subjetiva, el beneficio dependerá finalmente tanto de las intenciones del lector como de su disposición hacia la comprensión del paradigma orientado a objetos, así como de que se entienda que la asimilación de un nuevo enfoque de programación no es excluyente de otros, sino que la diversidad de enfoques de solución o formas de resolver un problema, amplían el repertorio de conocimientos, herramientas y capacidades en pro de ser progresiva y eventualmente mejores programadores.

   Para ilustrar y complementar de mejor manera tanto el diseño como los conceptos relacionados con los objetos, el blog se apoya de diagramas de clase UML para su correspondiente representación, por lo que sería también de mucha utilidad poseer bases de dicho lenguaje de modelado; sin embargo, tampoco son indispensables.

   La intención del blog es también la de introducir al lector en algunas de las estructuras de datos más convencionales y al mismo tiempo, utilizarlas para ilustrar los conceptos del paradigma orientado a objetos a través de su implementación.

     Finalmente, insisto en que este blog tiene una naturaleza introductoria pero no por ello informal. Confío plenamente en que puede servir como el inicio de un largo camino en la asimilación progresiva de los conceptos asociados con el paradigma orientado a objetos. Espero sinceramente haber podido alcanzar la meta de transmitir los conceptos fundamentales de la orientación a objetos, así como su aplicación en las estructuras de datos utilizando como medios a los lenguajes de programación Java y C++.