martes, 20 de mayo de 2008

Cuatro propiedades esenciales

Existen cuatro propiedades esenciales soportadas por el paradigma orientado a objetos: Abstracción, Encapsulación, Herencia, y Polimorfismo. Juntos representan un poderoso conjunto de aspectos, que pueden ser aplicados para resolver un problema mediante una conveniente aplicación de estos aspectos, uno puede construir una estructura para resolver problemas nuevos que usan componentes (las clases) desarrolladas para soluciones previas del problema.

Abstracción de Datos.

Consiste en la extracción de las propiedades fundamentales de un concepto. Permite no preocuparse por los detalles no esenciales, es decir, no es necesario conocer los detalles exactos de la implementación. Existe casi en todos los lenguajes de programación. Las estructuras de datos y los tipos de datos son un ejemplo de abstracción.

Una abstracción tiene existencia conceptual más bien que concreta. Representa ideas, conceptos, y propiedades generales sin la atención a detalles. Para el software de computadora, esto significa sin la atención a los detalles de implementación, evitando así la necesidad de confundirse con la sintaxis del lenguaje o la elección de un lenguaje. El único interés es que un lenguaje particular soporte la abstracción.

La abstracción es muy importante en las fases iniciales de una solución del problema (con el que uno se se esta enfrentando), donde se hace un intento para comprender el espacio del problema y las técnicas requeridas para una solución. Aunque se distribuyen eventualmente con detalles, la abstracción hace lo posible para delegar esos detalles y para organizar los a todos de una manera manejable mediante el uso de abstracciones de capa. Una abstracción de capa es una abstracción que esta variando los niveles de detalle. En el nivel más alto o primer nivel hay muy poco detalle. La abstracción del nivel más alto se expresan desde el punto de vista de un número pequeño de abstracciones de niveles más inferiores. La particionalidad continúa en cada nivel hasta que todos los detalles han sido incluidos.

Es por lo tanto la abstracción un modelo que incluye todas las capacidades esenciales, propiedades, o los aspectos que están siendo modelado sin algunos detalles extraños.

Hay varios tipos importantes de abstracción, dependiendo sobre qué esta siendo modelado.

  1. Abstracciones de objeto - Los objetos son las abstracciones que modelan la aplicación individual del dominio o entidades del espacio de solución.
  2. Abstracciones de clases - Las clases son las plantillas abstractas que modelan la aplicación similar del dominio o entidades del espacio de solución.
  3. Abstracciones de datos - Modela los datos que son usados cuando se comunican con el atributo de objetos y las clases.
  4. Abstracciones funcionales - Modela operaciones secuenciales considerando los procesos de abstracciones.
  5. Abstracciones de procesos - Modelan las operaciones concurrentes. Ambas abstracciones funcional y de procesos se usan cuando se comunican con las operaciones de objetos y las clases.
  6. Abstracciones de excepción - Las condiciones del error del modelo de excepción son el error manejado y se usan para crear objetos robustos y clases.

Por lo tanto la abstracción se define como la extracción de las propiedades esenciales de un concepto. En un programa estructurado, es suficiente conocer que un procedimiento dado realiza una tarea específica. El cómo se realiza la tarea no es importante; mientras el procedimiento sea fiable, se puede utilizar sin tener que conocer como funciona su interior. Esto se conoce como una abstracción funcional. Con la abstracción de datos, las estructuras de datos e ítems se pueden utilizar sin preocuparse sobre los detalles exactos de la implementación.

Polimorfismo

En la POO el polimorfismo se refiere al hecho de que una misma operación puede tener diferente comportamiento en diferentes objetos. En otras palabras, diferentes objetos reaccionan al mismo mensaje de manera diferente.

Por ejemplo, supongamos un número de figuras geométricas que responden todas al mensaje Dibujar. Cada objeto reacciona a este mensaje visualizando su figura en la pantalla. Obviamente, el mecanismo real para dibujar los objetos difiere de una figura a otra, pero todas las figuras realizan esta tarea en respuesta al mismo mensaje.

Polimorfismo se define como la calidad o estado de ser capaz de asumir formas diferentes. En la solución de un problema orientado a objetos, polimorfismo puede aplicarse a cualquier objetos u operaciones. El uso más común es la operación polimorfismo, que es representada por enviar el mismo mensaje, imprimirlo, a objetos diferentes y cada uno puede ser responder en su propia manera.

Polimorfismo puede examinarse desde el punto de vista de sus propiedades suplementarias. Una primera propiedad del polimorfismo es el sobrecarga de identificadores de mensaje y operadores. Polimorfismo es apoyado por la ligadura de un método particular al identificador del mensaje durante la ejecución de un sistema de software. Esta ligadura lenta, o ligadura dinámica, es un aspecto importante de la solución de un problema orientado a objetos.

Una de las características más importantes de la programación orientada a objetos es la capacidad de que diferentes objetos responden a órdenes similares de modo diferentes.

Identificador de mensaje y operadores sobrecargados. El identificador de mensaje y operador invocan una operación específica sobre un objeto. Cada uno establece la selección del significado uniforme de la operación en particular que se desea realizar, es decir, son utilizados para representar el concepto de una operación e identificar que se ejecutara o realizará.


Herencia

Es la propiedad que permite a los objetos construirse a partir de otros objetos. Este principio consiste en que cada clase puede dividirse en subclases, es decir, a partir de una clase base se pueden derivar otras clases (clases derivadas) que comparten características comunes con la clase de la que se derivan, además de tener sus propias características particulares.

La Herencia permite definir nuevas clase a partir de clases ya existentes. Si una clase sólo recibe características de una clase base, la herencia es simple.

Si una clase recibe propiedades de más de una clase base, la herencia es múltiple (*).

Ejemplo de Clases Derivadas

Las instancias heredan (usualmente) todas, y únicamente, las características de las clases a las que pertenecen, pero, también, es posible, en un sistema orientado a objetos, que se permita que las clases hereden características de superclases más generales. En ese caso, las características heredadas pueden ser ignoradas (overriden) y se pueden agregar características adicionales para tratar excepciones.

La herencia es el acto de adquirir una posesión, condición, o característica de generaciones pasadas. En la solución de un problema de computadora se habla de componentes de software que heredan propiedades que describen otros componentes de software. En la solución de un problema orientado a objetos un tipo de objeto hereda propiedades que caracterizan otro tipo de objeto. Desde las propiedades de objetos son dadas por la descripción de la clase, esto implica una jerarquía de clases, donde una clase es un subclase de otra, la clase padre. Los objetos que son los instancias de las subclases tienen propiedades dadas dentro de la descripción de la subclase así como también propiedades heredadas dadas dentro de la clase padre y todas las clases antecesoras.

Así la herencia provee la potencialidad para construir soluciones nuevas a problemas agregando el incremento de la capacidad a soluciones existentes del problema mediante subclases.

Las instancias de una subclase representan una especialización de instancias descritas por una clase padre. La instancia de la subclase tiene todos los atributos dados por la clase padre, más los atributos adicionales o agregados de la subclase. La instancia de la subclase responde al mismo conjunto de mensajes dados en la clase padre, los mensajes adicionales se dan en la descripción de la subclase.

La respuesta de la instancia de la subclase a los mensajes en la clase padre puede ser diferente de la respuesta de una clase padre de una instancia al mismo mensaje. No es valido considerar subclases de objetos que tengan menos atributos que los objetos descritos por la clase padre.


Concepturalización de la herencia

Una clase utilizada para derivar nuevas clases se conoce como clase base (padre, ascendiente), y una clase creada de otra clase se llama clase derivada (hija, descendiente, subclase).

En un lenguaje Orientado a Objetos la herencia se manifiesta con la creación de un tipo definido por el usuario (Clase), que puede heredar las características de otra clase ya existente o derivar las suyas a otra nueva clase. Cuando se hereda, las clases derivadas reciben las características (estructuras de datos y funciones) de la clase original , a las que se pueden añadir nuevas características o modificar las características heredadas.

La herencia se aplica para extender y reutilizar el código existente:

  • Los objetos se pueden construir de modo incremental a partir de otros objetos y pueden compartir código y estructuras de datos
  • Los algoritmos generales se pueden escribir de modo que se pueden reutilizar para nuevos tipos de objetos, incluso después que los algoritmos originales se han compilado.

Herencia simple :

Se realiza tomando una clase existente y derivando nuevas clases de ella . La clase derivada hereda las estructuras de datos y funciones de la clase original, Además, se pueden añadir nuevos miembros a las clases derivadas y los miembros heredados pueden ser modificados. Una clase utilizada para derivar nuevas clases se denomina clase base (padre, superclase, ascendiente). una clase creada de otra clase se denomina clase derivada o subclase. A su vez una clase derivada puede ser utilizada como una clase base para derivar más clases. Por consiguiente, se pueden construir jerarquías de clases, en las que cada clase sirve como padre o raíz de una nueva clase

Herencia Múltiple :

Es aquella en la cual una clase derivada tiene más de una clase base. Aunque el concepto de herencia múltiple es muy útil, el diseño de clases suele ser más complejo, y en ocasiones es preferible realizar la aplicación con herencia múltiple mediante emulación de herencia simple.

(*) Java NO soporta herencia multiple ya que trae numerosos inconvenientes. Para "simular" la herencia multiple se usan interfases.


Encapsulamiento

Las estructuras de datos y los detalles de la realización de un objeto se hallan ocultos de otros objetos del sistema. La única forma de acceder al estado de un objeto es enviar un mensaje que haga que uno de los métodos se ejecute. Estrictamente hablando, los atributos son escrituras taquigráficas para los métodos que obtienen y colocan valores. Esto hace que los tipos de objetos sean equivalentes a los tipos de datos abstractos en programación, en términos generales.

El resultado de encapsulación es una entidad con fronteras distintas, una interface bien definida, y una representación interna protegida. Para el software de computadora, una encapsulación es un componente de software. La integridad del componente de software como una encapsulación es dependiente de aspectos del lenguaje de computadora en el que se implementa el componente.

Encapsulación es un concepto importante para el desarrollo de soluciones del problema que son menos susceptibles a los errores. Un problema es particionado en un número de componentes. Cada componente es encapsulado para interactuar recíprocamente con los otros componentes únicos de manera cuidadosamente prescribidas, como definidas por su interface.

En un problema orientado a objetos que resuelve la unidad de encapsulación es el objeto. Los objetos son abstracciones encapsuladas.

Combinación de principios

La encapsulación es la combinación de los principios de ingeniería de software de modularidad, localización, y ocultamiento de información. Cada una de estas es muy importante para el desarrollo de un sistema eficiente, formal y sostenible.

  • Modularidad - El propósito determinado es particionar requerimientos, el diseño, y software en colecciones o grupos de complejidad y tamaño apropiado, uniforme con las metas de ingeniería de software. Modularidad se usa para construir componentes más grandes y operaciones más pequeñas en el diseño orientado a objetos que cuando se usan métodos funcionales debido a que:

- Los módulos - Son creados para abstracciones del objeto más que abstracciones funcionales

- Las operaciones - Se deben asignarse y encapsularse dentro del objeto y clase.

  • Localización - El propósito determinado es particionar requerimientos, el diseño y software así que los recursos lógicamente ligados son físicamente agrupados para aumentar la cohesión y para decrecer el acoplamiento. Es más importante localizar una abstracción completa que crear un módulo pequeño.
  • Ocultamiento de Información - Es la consideración del ocultamiento de información (p. ej. diseño, la decisión, los detalles de implementación) a fin de promover la abstracción, soporte al desarrollo ascendente/descendente (top-down) , protege contra la corrupción accidental, y promociona el logro de metas de ingeniería de software. Los recursos de un componente deberían ocultarse a menos que específicamente se necesiten por otro componente. Los datos globales comunes no son usados, pero más bien los atributos se ocultan dentro de objetos y las clases. Cada componente debería dividirse en 2 partes desarrolladas separadamente (y compilables): la especificación (o interface) y el cuerpo (o implementación).

lunes, 19 de mayo de 2008

¿Qué es la programación orientada a objetos?

Programación Orientada a Objetos.


La programación Orientada a objetos (POO) es una forma especial de programar, más cercana a como expresaríamos las cosas en la vida real que otros tipos de programación.

Con la POO tenemos que aprender a pensar las cosas de una manera distinta, para escribir nuestros programas en términos de objetos, propiedades, métodos y otras cosas que veremos rápidamente para aclarar conceptos y dar una pequeña base que permita soltarnos un poco con este tipo de programación.

Motivación

Durante años, los programadores se han dedicado a construir aplicaciones muy parecidas que resolvían una y otra vez los mismos problemas. Para conseguir que los esfuerzos de los programadores puedan ser utilizados por otras personas se creó la POO. Que es una serie de normas de realizar las cosas de manera que otras personas puedan utilizarlas y adelantar su trabajo, de manera que consigamos que el código se pueda reutilizar.

La POO no es difícil, pero es una manera especial de pensar, a veces subjetiva de quien la programa, de manera que la forma de hacer las cosas puede ser diferente según el programador. Aunque podamos hacer los programas de formas distintas, no todas ellas son correctas, lo difícil no es programar orientado a objetos sino programar bien. Programar bien es importante porque así nos podemos aprovechar de todas las ventajas de la POO.

Cómo se piensa en objetos

Pensar en términos de objetos es muy parecido a cómo lo haríamos en la vida real. Por ejemplo vamos a pensar en un coche para tratar de modelizarlo en un esquema de POO. Diríamos que el coche es el elemento principal que tiene una serie de características, como podrían ser el color, el modelo o la marca. Además tiene una serie de funcionalidades asociadas, como pueden ser ponerse en marcha, parar o aparcar.

Pues en un esquema POO el coche sería el objeto, las propiedades serían las características como el color o el modelo y los métodos serían las funcionalidades asociadas como ponerse en marcha o parar.

Por poner otro ejemplo vamos a ver cómo modelizaríamos en un esquema POO una fracción, es decir, esa estructura matemática que tiene un numerador y un denominador que divide al numerador, por ejemplo 3/2.

La fracción será el objeto y tendrá dos propiedades, el numerador y el denominador. Luego podría tener varios métodos como simplificarse, sumarse con otra fracción o número, restarse con otra fracción, etc.

Estos objetos se podrán utilizar en los programas, por ejemplo en un programa de matemáticas harás uso de objetos fracción y en un programa que gestione un taller de coches utilizarás objetos coche. Los programas Orientados a objetos utilizan muchos objetos para realizar las acciones que se desean realizar y ellos mismos también son objetos. Es decir, el taller de coches será un objeto que utilizará objetos coche, herramienta, mecánico, recambios, etc.

Clases en POO

Las clases son declaraciones de objetos, también se podrían definir como abstracciones de objetos. Esto quiere decir que la definición de un objeto es la clase. Cuando programamos un objeto y definimos sus características y funcionalidades en realidad lo que estamos haciendo es programar una clase. En los ejemplos anteriores en realidad hablábamos de las clases coche o fracción porque sólo estuvimos definiendo, aunque por encima, sus formas.

Propiedades en clases

Las propiedades o atributos son las características de los objetos. Cuando definimos una propiedad normalmente especificamos su nombre y su tipo. Nos podemos hacer a la idea de que las propiedades son algo así como variables donde almacenamos datos relacionados con los objetos.

Métodos en las clases

Son las funcionalidades asociadas a los objetos. Cuando estamos programando las clases las llamamos métodos. Los métodos son como funciones que están asociadas a un objeto.

Objetos en POO

Los objetos son ejemplares de una clase cualquiera. Cuando creamos un ejemplar tenemos que especificar la clase a partir de la cual se creará. Esta acción de crear un objeto a partir de una clase se llama instanciar (que viene de una mala traducción de la palabra instace que en inglés significa ejemplar). Por ejemplo, un objeto de la clase fracción es por ejemplo 3/5. El concepto o definición de fracción sería la clase, pero cuando ya estamos hablando de una fracción en concreto 4/7, 8/1000 o cualquier otra, la llamamos objeto.

Para crear un objeto se tiene que escribir una instrucción especial que puede ser distinta dependiendo el lenguaje de programación que se emplee, pero será algo parecido a esto.

miCoche = new Coche()

Con la palabra new especificamos que se tiene que crear una instancia de la clase que sigue a continuación. Dentro de los paréntesis podríamos colocar parámetros con los que inicializar el objeto de la clase coche.

Estados en objetos

Cuando tenemos un objeto sus propiedades toman valores. Por ejemplo, cuando tenemos un coche la propiedad color tomará un valor en concreto, como por ejemplo rojo o gris metalizado. El valor concreto de una propiedad de un objeto se llama estado.

Para acceder a un estado de un objeto para ver su valor o cambiarlo se utiliza el operador punto.

miCoche.color = rojo

El objeto es miCoche, luego colocamos el operador punto y por último el nombre e la propiedad a la que deseamos acceder. En este ejemplo estamos cambiando el valor del estado de la propiedad del objeto a rojo con una simple asignación.

Mensajes en objetos

Un mensaje en un objeto es la acción de efectuar una llamada a un método. Por ejemplo, cuando le decimos a un objeto coche que se ponga en marcha estamos pasándole el mensaje “ponte en marcha”.

Para mandar mensajes a los objetos utilizamos el operador punto, seguido del método que deseamos invocar.

miCoche.ponerseEnMarcha()

En este ejemplo pasamos el mensaje ponerseEnMarcha(). Hay que colocar paréntesis igual que cualquier llamada a una función, dentro irían los parámetros.

Otras cosas

Hay mucho todavía que conocer de la POO ya que sólo hemos hecho referencia a las cosas más básicas. También existen mecanismos como la herencia y el polimorfismo que son unas de las posibilidades más potentes de la POO.

La herencia sirve para crear objetos que incorporen propiedades y métodos de otros objetos. Así podremos construir unos objetos a partir de otros sin tener que reescribirlo todo.

El polimorfismo sirve para que no tengamos que preocuparnos sobre lo que estamos trabajando, y abstraernos para definir un código que sea compatible con objetos de varios tipos.

Son conceptos avanzados que cuesta explicar en las líneas de ese informe. No hay que olvidar que existen libros enteros dedicados a la POO y aquí solo pretendemos dar un repaso a algunas cosas para que "les suenen" cuando tengan que ponerse delante de ellas en los lenguajes de programación.


Fuente

Las Clases

Declaración de Clases
La sintaxis para declarar una clase es:

[modificadores] class id_clase

  • [modificadores] determinan la accesibilidad que otras clases tendrán sobre ella, pueden tener los valores public, abstract o final.
  • id_clase es el nombre que se le dará a la clase.

Los métodos
La sintaxis para los métodos es:

[modificadores] tipo_retorno id_metodo ([argumentos]) {

bloque_codigo_metodo

}

  • [modificadores] representan palabras clave que modifican la forma en que los métodos son accedidos.
  • tipo_retorno indica el tipo del valor (si existe) que el método devuelve. Si el método devuelve un valor, el tipo del mismo debe ser declarado. Si el método no devuelve ningún valor, se utiliza la palabra void.
  • id_método es el nombre del método.
  • [argumentos] representan una lista de variables cuyos valores son pasados al método para ser usados por él. Un método que no acepta argumentos se declara incluyendo solamente el paréntesis que abre y cierra.

La sintaxis para el método main es:

public static void main (String args[])

  • contiene dos modificadores requeridos: public y static
  • no devuelve ningún valor, por lo que el tipo de retorno es void.
  • acepta cero o más objetos de tipo String (String args[]). Esta sintaxis le permite ingresar los valores a ser usados desde la línea de comandos durante la ejecución.

domingo, 18 de mayo de 2008

Identificación de los Grupos de Productos de la Tecnologia Java

  • Java™ 2 Platform, Standard Edition (J2SE™) - Permite el desarrollo de applets y aplicaciones que ejecutan en el navegador Web y sobre el escritorio del computador, respectivamente. Por ejemplo, podemosusted puede utilizar el J2SE Software Developerʹs Kit (SDK) para crear un programa procesador de palabras para un computador personal.
  • Java™ 2 Platform, Enterprise Edition (J2EE™) - Permite crear grandes aplicaciones empresariales distribuidas cliente-servidor. Por ejemplo, podemos utilizar el J2EE SDK para crear una aplicación correspondiente al sitio web de una compañía de ventas al por menor, implementando sobre él una tienda virtual (eCommerce)
  • Java™ 2 Platform, Micro Edition (J2ME™) - Permite crear aplicaciones para dispositivos electrónicos con recursos restringidos. Por ejemplo, podemos utilizar J2ME SDK para crear un juego que ejecute en un teléfono móvil.

instalar JDK en Linux

Claro, me di cuenta que con el comando java no iba a compilar nada, y es porque solo tengo instalado jre (Java Runtime Environment), me falta jdk (Java Development Kit), que ahora le llaman Java SE (Standard Edition), asique aqui vamos...

1 - ir a http://download.java.net/jdk6/
2 - Bajar "Linux self-extracting JDK file" (en mi caso el .bin, ya que tengo Slack y no maneja nativamente rpms)
3 - Una vez bajado, abrir una terminal de linux y hacer una de las siguientes opciones:
a - chmod u+x archivojdk.bin
./archivojdk.bin
b - sh archivojdk.bin

4 - una vez ejecutado, nos aparecerá la Eula, con lo que presionamos "q" y escribimos "yes"
5 - Tras descomprimir todo, nos dejará un directorio, dentro del cual se encuentra el jdk.

Modificación del Path de nuestro usuario.

con un simple
PATH=PATH:~/Dirjdk

tendriamos resuelto el temita del path (para poder llamar al compilador desde cualquier directorio), pero con ese comando, nuestra variable PATH sería válida para esa terminal....
Para hacer un PATH válido en toda nuestra sesión, simplemente creamos un archivo llamado .profile (con el punto al principio) en la raiz de nuestro home (por ejemplo, /home/bita/.profile) y dentro, escribimos
PATH=$PATH:/home/bita/jdk
export PATH

y ya está, cuando iniciemos una terminal, tendremos en nuestro PATH el dir de jdk, lo podemos comprobar con
echo $PATH

Una Aplicación Simple, “HOLA MUNDO”

Como cualquier otro lenguaje de programación, el lenguaje de programación Java se utiliza para crear aplicaciones. En el Código siguiente se muestra una aplicación Java que despliega un mensaje de bienvenida.

1 //
2 // Ejemplo de Aplicación "Hola, Mundo"
3 //
4 public class TestGreeting {
5 public static void main (String[] args) {
6 Greeting hello = new Greeting();
7 Hello.greet();
8 }
9 }

10 public class Greeting {
11 public void greet() {
12 System.out.println("HOLA MUNDO");
13 }
14 }


La Aplicación TestGreeting:

  • Las Líneas 1–3 en el programa son líneas comentadas.
  • La Línea 4 declara el nombre de la clase como TestGreeting. Cuando se compila el archivo fuente, se crea un archivo nombreClase.class, donde nombreClase es el indicado en el archivo fuente. En este caso, el compilador crea un archivo llamado TestGreeting.class. Este contiene el código compilado para la clase pública TestGreeting.
  • En la línea 5 el programa comienza a ejecutarse. El intérprete de la tecnología Java debe encontrar esto definido exactamente en esta forma o no ejecutará el programa.Si al programa se le pasan argumentos desde la línea de comandos, estos son trasladados al método main() en un arreglo de String, denominado args. En este ejemplo, no se utiliza ningún argumento.

    - public - Indica que cualquiera puede acceder al método main(), incluyendo el intérprete de tecnología Java.
    - static - Esta palabra clave le indica al compilador que el método main() es usable dentro del contexto de la clase TestGreeting. No es necesario crear una instancia de la clase para ejecutar sus métodos estáticos.
    - void - Esta palabra clave indica que el método main() no devuelve ningún valor. Esto es importante porque el lenguaje de programación Java realiza cuidadosos chequeos de tipos para confirmar que los métodos llamados devuelven los tipos con que fueron declarados.
    - String args[] - Este método declara un sólo parámetro para el método main (de nombre args) y este es del tipo arreglo de String. Cuando se llama a este método, el parámetro args contiene los argumentos escritos en la línea de comandos a continuación del nombre de la clase, por ejemplo: java TestGreeting args[0] args[1]…
  • La línea 6 ilustra cómo crear un objeto, referenciado por la variable hello. La sintaxis new Greeting le indica al intérprete que debe construir un nuevo objeto de la clase Greeting.
  • La línea 7 demuestra la llamada a un método de un objeto. Esta llamada le indica al objeto hello que salude (greet) al mundo. La implementación de este método se muestra en las líneas 3-5 del archivo Greeting.java.
  • En las líneas 8-9 del programa, las dos llaves cierran el método main() y la clase TestGreeting, respectivamente.

La Clase Greeting

  • La línea 1 declara la clase Greeting.
  • Las líneas 2-4 demuestran la declaración de un método-declarado public- accesible al programa TestGreeting. El mismo no devuelve un valor, por lo tanto, se utiliza void como el tipo de retorno. El método greet envía una cadena de caracteres al flujo de salida estándar. El método println() se usa para escribir este mensaje al flujo de salida estándar.
  • La línea 5 cierra la declaración de la clase Greeting.