viernes, 29 de octubre de 2010

Leer y Escribir un fichero de texto

En java tenemos muchas posibilidades para leer y escribir ficheros de texto, binarios, con formato xml, etc, etc. En este tutorial nos vamos a centrar en escribir y leer ficheros de texto llano. Vermos también la clase JFileChooser que permite mostar una ventana para que el usuario navegue por los directorios y elija un fichero. No nos meteremos en profunidades, sólo lo básico para empezar a escribir y leer ficheros.


La clase JFileChooser

Siguiendo con nuestro editor de textos sencillo, dos de las acciones que debemos implementar en nuestro menú son las de salvar el texto en fichero y leer el texto de un fichero. En ambos casos hay que darle oportunidad al usuario de elegir el fichero bien para salvar, bien para leer.

La clase JFileChooser muestra directamente una ventana que permite navegar por los directorios y elegir un fichero. Un uso simple de esta clase es realmente sencillo.

Para pedir un fichero para abrirlo y leerlo basta hacer dos líneas de código

JFileChooser fileChooser = new JFileChooser();
int seleccion = fileChooser.showOpenDialog(areaTexto);

Veremos el parámetro areaTexto un poco más abajo. Por lo demás, listo, esto abre una ventana para navegar por los directorios y elegir un fichero similar a la de la figura

JFileChooser

Cuando el usuario termine, pulsará "Abrir" o "Cancelar". En el entero seleccion se nos guardará el botón que ha apretado. Sólo debemos comprobar si es el botón de "Abrir" para pedirle al JFileChooser qué fichero ha elegido el usuario y empezar a trabajar con él.

if (seleccion == JFileChooser.APPROVE_OPTION)
{
File fichero = fileChooser.getSelectedFile();
// y a trabajar con fichero ....
}

Si seleccion vale JFileChooser.APPROVE_OPTION es que el usuario ha pulsado "Abrir", así que pedimos el fichero seleccionado con getSelectedFile() y ... ¡¡¡ a trabajar !!!

Vale, vale, pero ¿qué es eso de pasarle el areaTexto en el parámetro?. La explicación es simple. JFileChooser abre una ventana que se mostrará junto a la ventana de nuestro editor. Nos gustaría que esta ventana de selección de fichero no se vaya detrás y quede oculta por la ventana del editor. La ventana de elegir fichero debería estar siempre delante y visible sobre el editor. La forma de conseguir esto es que JFileChooser sepa cual es esta ventana delante de la cual debe estar siempre. Para saber cual es esa ventana, basta con pasarle en el parámetro cualquier componente de dicha ventana. En nuestro ejemplo hemos decidido pasarle el JTextArea de nuestro editor, pero podíamos pasarle perfectamente el JMenuBar o el JFrame principal.

El JTextArea es una buena elección por un segundo motivo. Este código estará en las acciones de salvar y cargar texto de un fichero. El texto que se va a guardar o el que se lea se cojerá o meterá en el JTextArea. La clase AccionSalvar y AccionCargar deben tener accesible el JTextArea para leer de él el texto que tienen que guardar en fichero o para meter en él el texto que han leido del fichero. Puesto que tienen que tener el JTextArea de todas maneras, lo usaremos como parámetro del JFileChooser.

Para elegir un fichero para salvar, el código es exactamente igual, pero cambia el método para visualizar el diálogo.

JFileChooser fileChooser = new JFileChooser();
int seleccion = fileChooser.showSaveDialog(areaTexto);

La única diferencia es que cambia la etiqueta del botón "Abrir" por "Guardar".

Escribir un fichero de texto

Una vez elegido el fichero en el que queremos salvar el texto, simplemente debemos abrir el fichero para escritura y emepezar a escribir.

En java tenemos muchas clases y variantes para escribir ficheros: PrintStream, FileWriter, FileOutputStream, etc, etc. Todas hacen lo mismo, escribir en un fichero. La diferencia entre ellas suelen ser los métodos que tienen para escribir en el fichero o algunos aspectos internos, como si usan buffer o no. Algunas de ellas sólo tienen métodos para escribir bytes, otras permiten escribir String, etc, etc. Para elegir una de ellas, simplemente hay que ver qué tenemos, un File en nuestro caso y qué necesitamos, en nuestro caso algún método que nos permita escribir String.

Por supuesto, esta forma de elegir es muy tonta, pero nos vale para nuestro ejemplo. Si queremos "darle caña" al fichero escribiendo mucho y muy seguido quizás sea mejor pensar en qué clases son más eficientes en vez de en limitarnos a si tiene o no un método que nos resulte cómodo. Sin embargo, esto es tema para otro tutorial.

Para escribir fichero de texto llano a partir de un File, que es el que nos proporciona la clase JFileChooser, una clase ideal es PrintWriter. Simplemente con el siguiente código tenemos todo hecho

PrintWriter writer = new PrintWriter(fichero);
writer.print(areaTexto.getText());
writer.close();

Abrimos el fichero haciendo un new PrintWriter(), con print() escribimos el texto obtenido de areaTexto.getText() y cerramos el fichero.

PrintWriter tiene además muchos métodos que permiten escribir en formato texto llano números, cadenas, etc.

Leer un fichero

Para leer un fichero nos pasa algo parecido. Tenemos un montón de clases que leen ficheros FileInputStream, FileReader, InputStreamReader, BufferedReader. Igual que al escribir, es ver qué tenemos, un File, qué métodos queremos, alguno que nos permita leer String y elegir la clase que nos interese.

En el caso de la lectura es un poco más complejo. No hay una clase que admita File y tenga métodos para leer String. Mirando la API, vemos que el método readLine() que nos interesa y que es capaz de leer una línea y dárnosla como String está en la clase BufferedReader. Desgraciadamente esta clase admite en su constructor un Reader y no un File que es lo que tenemos. El asunto se nos complica un poco. Debemos buscar una clase que herede de Reader y que admita un File. Buscando, buscando, encontramos que FileReader cumple con estos requisitos.

Bueno, construir el BufferedReader es algo más complejo

BufferedReader reader = new BufferedReader(new FileReader(fichero));

BufferedReader va leyendo de línea en línea. No lee los retornos de carro. Debemos hacer un bucle para ir leyendo. Puede ser similar a este

String linea = reader.readLine();
while (linea != null)
{
// Aquí lo que tengamos que hacer con la línea puede ser esto
areaTexto.append(linea);
linea = reader.readLine();
}

Si hacemos esto y miramos el resultado nos llevamos el primer chasco. Salen todas las líneas seguidas, no sale cada línea en una línea. El problema es que readLine() nos devuelve la línea, pero sin el retorno de carro al final. Si vamos añadiendo en el area de texto, debemos añadir nosotros desde nuestro código los retornos de carro.

¿Cual es el retorno de carro?. En windows el retorno de carro consiste en dos caracteres seguidos /r/n. En unix el retorno de carro sólo es uno /n. ¿Qué ponemos para que nuestro programa siga siendo portable?. La clase System de java nos permite consultar este tipo de cosas. Si ponemos

String retornoDeCarro = System.getProperty("line.separator");

en retornoCarro obtendremos el retorno de carro adecuado para nuestro sistema operativo. En System.getProperties() de la API puedes ver una lista de cosas interesantes que se pueden obtener, como el nombre del sistema operativo, el directorio actual de ejecución o el nombre del usuario.

Nuestro código quedaría así

String linea = reader.readLine();
while (linea != null)
{
// Aquí lo que tengamos que hacer con la línea puede ser esto
areaTexto.append(linea);
areaTexto.append(System.getProperty("line.separator"));
linea = reader.readLine();
}

Por supuesto, no se nos debe olvidar cerrar el fichero cuando terminemos

reader.close();

La clase StringBuffer

En el ejemplo hemos ido componiendo el texto directamente sobre el area de texto, usando su método append().

Otra opción es componer el texto directamente sobre un String y luego añadirlo todo de golpe. El código quedaría más o menos así

String lineaTotal="";
String linea = reader.readLine();
while (linea != null)
{
lineaTotal = lineaTotal + linea + System.getProperty("line.separator");
linea = reader.readLine();
}
areaTexto.setText(lineaTotal);
reader.close();

Esta opción es válida, pero no es eficiente. Se crean demasiadas clases String intermedias que se dejan luego para el recolector de basura. Para este tipo de cosas, java tiene la clase StringBuffer. Es básicamente un String, pero que permite ser modificado, añadiendo y borrando cosas de forma eficiente.

El código con esta clase quedaría así

StringBuffer lineaTotal="";
String linea = reader.readLine();
while (linea != null)
{
lineaTotal.append(linea);
lineaTotal.append(System.getProperty("line.separator"));
linea = reader.readLine();
}
areaTexto.setText(lineaTotal.toString());
reader.close();

martes, 21 de septiembre de 2010

GUI segunda parte

//***************************************************************************

package paquete1;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;


import paquete2.operaciones;
import javax.swing.*;

public class interfaz {


JFrame frame;
JPanel mipanel;
JLabel lblnum1,lblnum2,lblnum3,lblresultado,lblspace1,lblspace2,lblspace3,lblspace4,lblspace5,lblspace6,lblspace7,lblspace8,lblspace9,lblspace10,lblspace11,lblspace12,lblspace13,lblspace14;
JButton boton,botonr,botond,botonm;
JTextField txtnum1,txtnum2,txtnum3,txtresultado;



public static void main(String[] arg){

interfaz miformulario = new interfaz();

}

// creo el constructor de la clase......
public interfaz(){

//1.creo el frame
frame = new JFrame("Calculadora de tercer semestre");
frame.setDefaultCloseOperation(JFrame.HIDE_ON_CLOSE);

// 2. creo el panel que contiene los objetos y le asigno la grilla
mipanel = new JPanel(new GridLayout(7,4));

//3. creo etiquetas o labels
lblnum1 = new JLabel("Primer Numero: ");
lblnum2 = new JLabel("Segundo Numero: ");
lblnum3 = new JLabel("Tercer Numero: ");
lblspace1 = new JLabel(" ");
lblspace2 = new JLabel(" ");
lblspace3 = new JLabel(" ");
lblspace4 = new JLabel(" ");
lblspace5 = new JLabel(" ");
lblspace6 = new JLabel(" ");
lblspace7 = new JLabel(" ");
lblspace8= new JLabel(" ");
lblspace9 = new JLabel(" ");
lblspace10 = new JLabel(" ");
lblspace11 = new JLabel(" ");
lblspace12 = new JLabel(" ");
lblspace13 = new JLabel(" ");
lblspace14 = new JLabel(" ");


lblresultado = new JLabel("El resultado es: ");

//4.creo los cuadros de texto y les doy un tamaño
txtnum1 = new JTextField(10);
txtnum2 = new JTextField(10);
txtnum3 = new JTextField(10);
txtresultado = new JTextField(10);

// 5- creo botones
boton = new JButton("Sumar");
botonr = new JButton("1");

//agrego los objetos al panel
mipanel.add(lblspace1);
mipanel.add(lblspace2);
mipanel.add(lblspace3);
mipanel.add(lblspace4);
mipanel.add(lblspace5);
mipanel.add(lblnum1);
mipanel.add(txtnum1);
mipanel.add(lblspace6);
mipanel.add(lblspace7);
mipanel.add(lblnum2);

mipanel.add(txtnum2);
mipanel.add(lblspace8);
mipanel.add(lblspace9);

mipanel.add(lblnum3);
mipanel.add(txtnum3);
mipanel.add(lblspace10);
mipanel.add(lblspace11);
mipanel.add(lblresultado);
mipanel.add(txtresultado);
mipanel.add(lblspace12);
mipanel.add(lblspace13);
mipanel.add(boton);
mipanel.add(botonr);
mipanel.add(lblspace14);

// agregamos el panel o contenedor al frame o formulario
frame.getContentPane().add(mipanel,BorderLayout.NORTH);


botonr.addActionListener(new ActionListener(){




public void actionPerformed(ActionEvent e) {
operaciones micalculadora= new operaciones();


String acum=txtresultado.getText()+"1";

// txtresultado.setText(String.valueOf(micalculadora.resta(Integer.parseInt(txtnum1.getText()), Integer.parseInt(txtnum2.getText()),Integer.parseInt(txtnum3.getText()))));

txtresultado.setText(acum);

}
});

frame.pack();
//frame.setSize(400, 200);
frame.setResizable(false);
frame.setVisible(true);

}


}
//**************************************************************************



este es el codigo para operaciones


package paquete2;

public class operaciones {

int resultado=0;

public int suma(int a,int b){

this.resultado=a + b;

return this.resultado;


}// cierre del afuncion suma


}// cierres de la clase operaciones

Capa GUI

package paquete1;

import java.awt.BorderLayout;
import java.awt.GridLayout;

import javax.swing.*;

public class interfaz {
//3.creo las instancias de los objetos....
JFrame miframe;
JPanel mipanel;
JLabel lblnum1,lblnum2;
JTextField txtnum1,txtnum2;
JButton boton;

//2. creo la funcion de inicio del programa main
public static void main(String[] arg){

interfaz miformulario = new interfaz();

}


// 1. creo un constructor que es una funcion con el nombre de la clase
public interfaz(){

//4. creo mis objetos utilizando las instancias creadas y primero creo el frame

miframe= new JFrame("Calculadora multifuncional");
miframe.setDefaultCloseOperation(JFrame.HIDE_ON_CLOSE);

//5. creo los paneles

mipanel = new JPanel(new GridLayout(4,2));

lblnum1 = new JLabel("Digite primer numero: ");
txtnum1=new JTextField(10);
lblnum2 = new JLabel("Digite segundo numero: ");
txtnum2=new JTextField(10);


mipanel.add(lblnum1);
mipanel.add(txtnum1);
mipanel.add(lblnum2);
mipanel.add(txtnum2);


//6. agregamos el panel al frame
miframe.getContentPane().add(mipanel,BorderLayout.NORTH);




miframe.pack();
miframe.setVisible(true);
miframe.setResizable(false);

}





}


//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++


Este es el codigo de la clase operaciones




package paquete2;

public class operaciones {

int resultado=0;


// funcion sumar
public int sumar(int a, int b){

this.resultado=a+b;

return this.resultado;
}// fin del funcion suma


}

martes, 31 de agosto de 2010

Agregue una nueva clase llamada Revista.java cuyo importe se basara en el día de la semana que se alquila.
Si es Sábado o Domingo el alquiler de las revistas será 5, en otro días será 2.

Alquiler3.java
public class Alquiler3 {
private int dias;
public Alquiler3(int dias) {
this.dias = dias;
}
public int getDias () {
return dias;
}
}
Item3.java
public class Item3 {
protected float calcularImporte(Alquiler3 contrato) {
return 0;
}
}
Pelicula3.java
public class Pelicula3 extends Item3 {
protected float calcularImporte(Alquiler3 contrato) {
int importe = 2*contrato.getDias();
return importe;
}
}
Equipo3.java
public class Equipo3 extends Item3 {
protected float calcularImporte(Alquiler3 contrato) {
int seguroEquipo = 50;
int importe = 5*contrato.getDias();
return seguroEquipo + importe;
}
}
Juego3.java
public class Juego3 extends Item3 {
String fabricante;
public Juego3(String fabricante) {
this.fabricante = fabricante;
}
public String getFabricante() {
return fabricante;
}
protected float calcularImporte(Alquiler3 contrato) {
String fabricante = this.fabricante;
int tasa = 0;
if (fabricante.equals("PlayStation")) tasa = 2;
if (fabricante.equals("Nintendo")) tasa = 1;
int importe = tasa*contrato.getDias();
return importe;
}
}
Libro3.java
public class Libro3 extends Item3 {
protected float calcularImporte(Alquiler3 contrato) {
return 0;
}
}
TestPolimorfismo.java
public class TestPolimorfismo {
public static void main (String[] args) {
Alquiler3 contrato = new Alquiler3(10);
Pelicula3 oscar = new Pelicula3();
System.out.println( oscar.calcularImporte(contrato) );
Equipo3 vhs = new Equipo3();
System.out.println( vhs.calcularImporte(contrato) );
Juego3 mu = new Juego3("Nintendo");
System.out.println( mu.calcularImporte(contrato) );
Libro3 quijote = new Libro3();
System.out.println( quijote.calcularImporte(contrato) );
}
}

lunes, 23 de agosto de 2010

Interfaces

Interfaces
Concepto de Interface

El concepto de Interface lleva un paso más adelante la idea de las clases abstractas. En Java una interface es una clase abstracta pura, es dcir una clase donde todos los métodos son abstractos (no se implementa ninguno). Permite al diseñador de clases establecer la forma de una clase (nombres de métodos, listas de argumentos y tipos de retorno, pero no bloques de código). Una interface puede también contener datos miembro, pero estos son siempre static y final. Una interface sirve para establecer un 'protocolo' entre clases.

Para crear una interface, se utiliza la palabra clave interface en lugar de class. La interface puede definirse public o sin modificador de acceso, y tiene el mismo significado que para las clases. Todos los métodos que declara una interface son siempre public.

Para indicar que una clase implementa los métodos de una interface se utiliza la palabra clave implements. El compilador se encargará de verificar que la clase efectivamente declare e implemente todos los métodos de la interface. Una clase puede implementar más de una interface.
Declaración y uso

Una interface se declara:

interface nombre_interface {
tipo_retorno nombre_metodo ( lista_argumentos ) ;
. . .
}

Por ejemplo:

interface InstrumentoMusical {
void tocar();
void afinar();
String tipoInstrumento();
}

Y una clase que implementa la interface:

class InstrumentoViento extends Object implements InstrumentoMusical {
void tocar() { . . . };
void afinar() { . . .};
String tipoInstrumento() {}
}

class Guitarra extends InstrumentoViento {
String tipoInstrumento() {
return "Guitarra";
}
}

La clase InstrumentoViento implementa la interface, declarando los métodos y escribiendo el código correspondiente. Una clase derivada puede también redefinir si es necesario alguno de los métodos de la interface.
Referencias a Interfaces

Es posible crear referencias a interfaces, pero las interfaces no pueden ser instanciadas. Una referencia a una interface puede ser asignada a cualquier objeto que implemente la interface. Por ejemplo:

InstrumentoMusical instrumento = new Guitarra();
instrumento.play();
System.out.prinln(instrumento.tipoInstrumento());

InstrumentoMusical i2 = new InstrumentoMusical(); //error.No se puede instanciar

Extensión de interfaces

Las interfaces pueden extender otras interfaces y, a diferencia de las clases, una interface puede extender más de una interface. La sintaxis es:

interface nombre_interface extends nombre_interface , . . . {
tipo_retorno nombre_metodo ( lista_argumentos ) ;
. . .
}

Agrupaciones de constantes

Dado que, por definición, todos los datos miembros que se definen en una interface son static y final, y dado que las interfaces no pueden instanciarse resultan una buena herramienta para implantar grupos de constantes. Por ejemplo:

public interface Meses {
int ENERO = 1 , FEBRERO = 2 . . . ;
String [] NOMBRES_MESES = { " " , "Enero" , "Febrero" , . . . };
}

Esto puede usarse simplemente:

System.out.println(Meses.NOMBRES_MESES[ENERO]);


Un ejemplo casi real

El ejemplo mostrado a continuación es una simplificación de como funciona realmente la gestión de eventos en el sistema gráfico de usuario soportado por el API de Java (AWT o swing). Se han cambiado los nombres y se ha simplificado para mostrar un caso real en que el uso de interfaces resuelve un problema concreto.

Supongamos que tenemos una clase que representa un botón de acción en un entorno gráfico de usuario (el típico botón de confirmación de una acción o de cancelación). Esta clase pertenecerá a una amplia jerarquía de clases y tendrá mecanismos complejos de definición y uso que no son objeto del ejemplo. Sin embargo podríamos pensar que la clase Boton tiene miembros como los siguientes.

class Boton extends . . . {
protected int x , y, ancho, alto; // posicion del boton
protected String texto; // texto del boton
Boton(. . .) {
. . .
}
void dibujar() { . . .}
public void asignarTexto(String t) { . . .}
public String obtenerTexto() { . . .)
. . .
}

Lo que aquí nos interesa es ver lo que sucede cuando el usuario, utilizando el ratón pulsa sobre el botón. Supongamos que la clase Boton tiene un método, de nombre por ejemplo click(), que es invocado por el gestor de ventanas cuando ha detectado que el usuario ha pulsado el botón del ratón sobre él. El botón deberá realizar alguna acción como dibujarse en posición 'pulsado' (si tiene efectos de tres dimensiones) y además, probablemente, querrá informar a alguien de que se ha producido la acción del usuario. Es en este mecanismo de 'notificación' donde entra el concepto de interface. Para ello definimos una interface Oyente de la siguiente forma:

interface Oyente {
void botonPulsado(Boton b);
}

La interface define un único método botonPulsado. La idea es que este método sea invocado por la clase Boton cuando el usuario pulse el botón. Para que esto sea posible en algún momento hay que notificar al Boton quien es el Oyente que debe ser notificado. La clase Boton quedaría:

class Boton extends . . . {
. . .
private Oyente oyente;
void registrarOyente(Oyente o) {
oyente = o;
}
void click() {
. . .
oyente.botonPulsado(this);
}
}

El método registrarOyente sirve para que alguien pueda 'apuntarse' como receptor de las acciones del usuario. Obsérvese que existe una referencia de tipo Oyente. A Boton no le importa que clase va a recibir su notificación. Simplemente le importa que implante la interface Oyente para poder invocar el método botonPulsado. En el método click se invoca este método. En el ejemplo se le pasa como parámetro una referencia al propio objeto Boton. En la realidad lo que se pasa es un objeto 'Evento' con información detallada de lo que ha ocurrido.

Con todo esto la clase que utiliza este mecanismo podría tener el siguiente aspecto:

class miAplicacion extends . . . implements Oyente {
public static main(String [] args) {
new miAplicacion(. . .);
. . .
}
. . .
miAplicacion(. . .) {
. . .
Boton b = new Boton(. . .);
b.registrarOyente(this);
}

. . .
void botonPulsado(Boton x) {
// procesar click
. . .
}
}

Obsérvese en el método registrarOyente que se pasa la referencia thisque en el lado de la clase Boton es recogido como una referencia a la interface Oyente. Esto es posible porque la clase miAplicacion implementa la interface Oyente . En términos clásicos de herencia miAplicacion ES un Oyente .

martes, 17 de agosto de 2010

Polimorfismo en Java

Hola muchachos!!!


Antes de iniciar con el tema de polimorfismo....recordemos algunos conceptos

Declaración de la clase

La clase se declara mediante la línea public class Contador. En el caso más general, la declaración de una clase puede contener los siguientes elementos:

[public] [final | abstract] class Clase [extends ClaseMadre] [implements Interfase1 [, Interfase2 ]…]

o bien, para interfaces:

[public] interface Interfase [extends InterfaseMadre1 [, InterfaseMadre2 ]…]

Como se ve, lo único obligatorio es class y el nombre de la clase. Las interfases son un caso de clase particular que veremos más adelante.
Public, final o abstract

Definir una clase como pública (public) significa que puede ser usada por cualquier clase en cualquier paquete. Si no lo es, solamente puede ser utilizada por clases del mismo paquete (más sobre paquetes luego; básicamente, se trata de un grupo de clases e interfaces relacionadas, como los paquetes de biblioteca incluídos con Java).

Una clase final (final) es aquella que no puede tener clases que la hereden. Esto se utiliza básicamente por razones de seguridad (para que una clase no pueda ser reemplazada por otra que la herede), o por diseño de la aplicación.

Una clase abstracta (abstract) es una clase que puede tener herederas, pero no puede ser instanciada. Es, literalmente, abstracta (como la clase Number definida en java.lang). ¿Para qué sirve? Para modelar conceptos. Por ejemplo, la clase Number es una clase abstracta que representa cualquier tipo de números (y sus métodos no están implementados: son abstractos); las clases descendientes de ésta, como Integer o Float, sí implementan los métodos de la madre Number, y se pueden instanciar.

Por lo dicho, una clase no puede ser final y abstract a la vez (ya que la clase abstract requiere descendientes…)

¿Un poco complejo? Se va a entender mejor cuando veamos casos particulares, como las interfases (que por definición son abstractas ya que no implementan sus métodos).
Extends

La instrucción extends indica de qué clase desciende la nuestra. Si se omite, Java asume que desciende de la superclase Object.

Cuando una clase desciende de otra, esto significa que hereda sus atributos y sus métodos (es decir que, a menos que los redefinamos, sus métodos son los mismos que los de la clase madre y pueden utilizarse en forma transparente, a menos que sean privados en la clase madre o, para subclases de otros paquetes, protegidos o propios del paquete). Veremos la calificación de métodos muy pronto, a no desesperar!
Implements

Una interfase (interface) es una clase que declara sus métodos pero no los implementa; cuando una clase implementa (implements) una o más interfases, debe contener la implementación de todos los métodos (con las mismas listas de parámetros) de dichas interfases.

Esto sirve para dar un ascendiente común a varias clases, obligándolas a implementar los mismos métodos y, por lo tanto, a comportarse de forma similar en cuanto a su interfase con otras clases y subclases.
Interface

Una interfase (interface), como se dijo, es una clase que no implementa sus métodos sino que deja a cargo la implementación a otras clases. Las interfases pueden, asimismo, descender de otras interfases pero no de otras clases.

Todos sus métodos son por definición abstractos y sus atributos son finales (aunque esto no se indica en el cuerpo de la interfase).

Son útiles para generar relaciones entre clases que de otro modo no están relacionadas (haciendo que implementen los mismos métodos), o para distribuir paquetes de clases indicando la estructura de la interfase pero no las clases individuales (objetos anónimos).

Si bien diferentes clases pueden implementar las mismas interfases, y a la vez descender de otras clases, esto no es en realidad herencia múltiple ya que una clase no puede heredar atributos ni métodos de una interface; y las clases que implementan una interfase pueden no estar ni siquiera relacionadas entre sí.


El polimorfismo es un concepto de la programación orientada a objetos que nos permite programar en forma general, en lugar de hacerlo en forma específica. En general nos sirve para programar objetos con características comunes y que todos estos compartan la misma superclase en una jerarquía de clases, como si todas fueran objetos de la superclase. Esto nos simplifica la programación.

Recuerde el ejemplo del ecosistema, en donde todos los objetos de las distintas especies heredaban de una superclase llamada Animal, que brindaba la información general de cualquier animal, independiente de su especie. Sin embargo, cada especie hace un uso particular de cada uno de los métodos u operaciones de la clase Animal. El método comer() no se ejecutará de la misma manera en un León() o en un Pavo(). Lo mismo ocurre para métodos moverse() en objetos de tipo Tiburón() o Gallina(), aunque todas las especies realicen estos métodos. A la sobrescritura o implementación específica de métodos es la clave del polimorfismo.

Para poner en práctica se hará un ejemplo bastante sencillo. Se hará una librería de clases que represente figuras tridimensionales y bidimensionales, y su respectiva jerarquía de clases. Las clases deben ser capaces de tener funcionamiento bastante básico, como obtener áreas, volúmenes y perímetros de la figura correspondiente.


La representación de la jerarquía sería como ésta:


Click a la imagen para verla más grande...


La superclase de dicha jerarquía podría ser muy parecida a ésta:

public abstract class figura {

protected String nombre;
protected int color;
protected int grosorBorde;

public String getNombre(){
return this.nombre;
}
public void setNombre(String n){
this.nombre=n;
}

public int getColor(){
return this.color;
}

public void setColor(int c){
this.color=c;
}

public int getGrosorBorde(){
return this.grosorBorde;
}

public void setGrosorBorde(int g){
this.grosorBorde=g;
}

public abstract void dibujar();
}

Las siguientes clases en el nivel de la jerarquía podrían quedar muy parecidas a éstas:

public abstract class figura2D extends figura {

public abstract int calcularArea();

public abstract int calcularPerimetro();
}

public abstract class figura3D extends figura {

public abstract int calcularVolumen();
}

Se le pide que forme las clases de la parte inferior de la jerarquía y que representarían los objetos a instanciarse.

Además, debe de realizar una implementación de esta librería, en donde el usuario pueda crear nuevas figuras y que éstas se almacenen en un arreglo de figuras.


Ejercicios:


* Realice una jerarquía de clases en donde se representen un cuadrilátero.


* Mediante esa superclase, realice las clases rectángulo, cuadrado, paralelogramo y trapezoide; que heredarán de ella, convirtiéndose prácticamente en objetos cuadrilátero (superclase).

martes, 10 de agosto de 2010

Taller HERENCIA -10 -08-2010

Ejercicio de diagnostico...POO

1.)Crea una clase CRectángulo. La clase tiene dos datos miembro, largo y ancho. La clase cuenta con
métodos que calculan el perímetro (obtenPerímetro) y el área (obtenÁrea) del rectángulo, así como
métodos para obtener y poner los valores correspondientes a los atributos largo y ancho. Los métodos
poner deben comprobar que tanto largo como ancho sean mayores que 0 y menores que 20.



Probar y analizar

2.)Construir una clase final Math2 que amplíe las declaraciones de métodos estáticos de la clase
Math y que incluya funciones que devuelvan, respectivamente, el máximo, el mínimo, el
sumatorio, la media aritmética y la media geométrica de un array de números reales dado como
parámetro.



Solucion....

public final class Math2 {
public static double min (double [] v) {
double menor = v[0];
for (int i=0; i<"v.length"; i++) {
if (menor>v[i]) { menor=v[i]; }
}
return menor;
}
public static double max (double [] v) {

double mayor = v[0];
for (int i=0; i<"v.length"; i++) {
if (mayor}
return mayor;
}
public static double sum (double [] v) {
double sumatorio =0.0;
for (int i=0; i<"v.length"; i++) {
sumatorio=sumatorio+v[i];
}
return sumatorio;
}
public static double mediaAritmetica (double [] v) {
double sumatorio =0.0;
for (int i=0; i<"v.length"; i++) {
sumatorio+=v[i];
}
return (sumatorio/"v.length");
}
public static double mediaGeometrica (double [] v) {
double producto =1.0;
for (int i=0; i<"v.length"; i++) {
producto*=v[i];
}
return Math.sqrt(producto);
}
}
Ejemplo de uso de la clase Math2:
/**
* Programa PruebaMath2
* A. Garcia-Beltran - diciembre, 2004
*/
public class PruebaMath2 {
public static void main (String [] args) {
double [] x = new double[10];
for (int i=0; i<"x.length"; i++) {
x[i] = 5*Math.random();
System.out.println("x["+i+"] = "+x[i]);
}
System.out.println("Minimo : " + Math2.min(x));
System.out.println("Maximo : " + Math2.max(x));
System.out.println("Sumatorio : " + Math2.sum(x));
System.out.println("Media arit. : " + Math2.mediaAritmetica(x));
System.out.println("Media geom. : " + Math2.mediaGeometrica(x));
}
}


Salida por pantalla de la ejecución del código anterior:
$>java PruebaMath2
x[0] = 3.9295964172220037
x[1] = 3.3033982387050598
x[2] = 0.38413320538334517
x[3] = 1.441533972096129
x[4] = 0.5194720253569335
x[5] = 0.5801662478628711
x[6] = 4.370186448410964
x[7] = 1.2908820504663692
x[8] = 3.8520244358555944
x[9] = 0.1450533020411976
Minimo : 0.1450533020411976
Maximo : 4.370186448410964
Sumatorio : 19.816446343400468
Media arit. : 1.981644634340047
Media geom. : 2.6131642597311173

3.)Diseñe una clase cualquiera donde se muestre un ejemplo de sobrecarga de metodos...

miércoles, 4 de agosto de 2010

Ejercicios Herencia

Saludos a todos!!!! ....Leer y analizar.


1.)Construir una clase Factura que descienda de la clase Precio y que incluya dos atributos
específicos llamados emisor y cliente y, al menos, un método llamado
imprimirFactura.

Solucion.
Clase Factura descendiente de la clase Precio y que incluye dos atributos específicos
llamados emisor y cliente y un método llamado imprimirFactura....Usted segun esta solucion debe construir la clase precio.
/**
* Declaracion de la clase Factura
* descendiente de la clase precio
*/
public class Factura extends Precio {
public int cliente;
private final String emisor = "Almacenes ACME S.A";
public void imprimirFactura () {
System.out.println("");
System.out.println("Emisor: " + emisor);
System.out.println("----------------------");
System.out.println("Cliente: " + cliente);
System.out.println("Total: " + euros + " euros");
}
}
Ejemplo de uso de la clase Factura:
/**
* Programa PruebaFactura
* A. Garcia-Beltran - diciembre, 2004
*/
public class PruebaFactura {
public static void main (String [] args) {
Factura f = new Factura();
f.cliente = 12345;
f.pone(1000);
f.imprimirFactura();
}
}
Salida por pantalla de la ejecución del código anterior:
$>java pruebaFactura
Emisor: Almacenes ACME S.A
----------------------
Cliente: 12345
Total: 1000.0 euros


______________________________________________________________________
2.) Una caja registradora es un aparato mecánico o electrónico que permite calcular y registrar transacciones comerciales, e incluye un cajón para guardar dinero. Por lo general, permite además imprimir un recibo o factura para el cliente, según las disposiciones legales de cada País. Crear una clase caja registradora que dependa de una clase padre calculadore(Suma pollos)....

martes, 3 de agosto de 2010

Herencia en java (II)

Herencia - II


El modificador de acceso protected

El modificador de acceso protected es una combinación de los accesos que proporcionan los modificadores public y private. protected proporciona acceso público para las clases derivadas y acceso privado (prohibido) para el resto de clases.

Por ejemplo, si en la clase Empleado definimos:

class Empleado {
protected int sueldo;
. . .
}

entonces desde la clase Ejecutivo se puede acceder al dato miembro sueldo, mientras que si se declara private no.

Up-casting y Down-casting

Siguiendo con el ejemplo de los apartados anteriores, dado que un Ejecutivo ES un Empleado se puede escribir la sentencia:

Empleado emp = new Ejecutivo("Máximo Dueño" , 2000);

Aquí se crea un objeto de la clase Ejecutivo que se asigna a una referencia de tipo Empleado. Esto es posible y no da error ni al compilar ni al ejecutar porque Ejecutivo es una clase derivada de Empleado. A esta operación en que un objeto de una clase derivada se asigna a una referencia cuyo tipo es alguna de las superclases se denomina 'upcasting'.

Cuando se realiza este tipo de operaciones, hay que tener cuidado porque para la referencia emp no existen los miembros de la clase Ejecutivo, aunque la referencia apunte a un objeto de este tipo. Así, las expresiones:

emp.aumentarSueldo(3); // 1. ok. aumentarSueldo es de Empleado
emp.asignarPresupuesto(1500); // 2. error de compilación

En la primera expresión no hay error porque el método aumentarSueldo está definido en la clase Empleado. En la segunda expresión se produce un error de compilación porque el método asignarPresupuesto no existe para la clase Empleado.

Por último, la situación para el método toString es algo más compleja. Si se invoca el método:

emp.toString(); // se invoca el metodo toString de Ejecutivo

el método que resultará llamado es el de la clase Ejecutivo. toString existe tanto para Empleado como para Ejecutivo, por lo que el compilador Java no determina en el momento de la compilación que método va a usarse. Sintácticamente la expresión es correcta. El compilador retrasa la decisión de invocar a un método o a otro al momento de la ejecución. Esta técnica se conoce con el nombre de dinamic binding o late binding. En el momento de la ejecución la JVM comprueba el contenido de la referencia emp. Si apunta a un objeto de la clase Empleado invocará al método toString de esta clase. Si apunta a un objeto Ejecutivo invocará por el contrario al método toString de Ejecutivo.

Operador cast

Si se desea acceder a los métodos de la clase derivada teniendo una referencia de una clase base, como en el ejemplo del apartado anterior hay que convertir explicitamente la referencia de un tipo a otro. Esto se hace con el operador de cast de la siguiente forma:

Empleado emp = new Ejecutivo("Máximo Dueño" , 2000);
Ejecutivo ej = (Ejecutivo)emp; // se convierte la referencia de tipo
ej.asignarPresupuesto(1500);

La expresión de la segunda línea convierte la referencia de tipo Empleado asignándola a una referencia de tipo Ejecutivo. Para el compilador es correcto porque Ejecutivo es una clase derivada de Empleado. En tiempo de ejecución la JVM convertirá la referencia si efectivamente emp apunta a un objeto de la clase Ejecutivo. Si se intenta:

Empleado emp = new Empleado("Javier Todudas" , 2000);
Ejecutivo ej = (Ejecutivo)emp;

no dará problemas al compilar, pero al ejecutar se producirá un error porque la referencia emp apunta a un objeto de clase Empleado y no a uno de clas Ejecutivo.

La clase Object

En Java existe una clase base que es la raíz de la jerarquía y de la cual heredan todas aunque no se diga explicitamente mediante la clausula extends. Esta clase base se llama Object y contiene algunos métodos básicos. La mayor parte de ellos no hacen nada pero pueden ser redefinidos por las clases derivadas para implementar comportamientos específicos. Los métodos declarados por la clase Object son los siguientes:

public class Object {
public final Class getClass() { . . . }
public String toString() { . . . }
public boolean equals(Object obj) { . . . }
public int hashCode() { . . . }
protected Object clone() throws CloneNotSupportedException { . . . }
public final void wait() throws IllegalMonitorStateException,
InterruptedException { . . . }
public final void wait(long millis) throws IllegalMonitorStateException,
InterruptedException {. . .}
public final void wait(long millis, int nanos) throws
IllegalMonitorStateException,
InterruptedException { . . . }
public final void notify() throws IllegalMonitorStateException { . . . }
public final void notifyAll() throws
IllegalMonitorStateException { . . . }
protected void finalize() throws Throwable { . . . }
}

Las cláusulas final y throws se verán más adelante. Como puede verse toString es un método de Object, que puede ser redefinido en las clases derivadas. Los métodos wait, notify y notifyAll tienen que ver con la gestión de threads de la JVM. El método finalize ya se ha comentado al hablar del recolector de basura.

Para una descripción exahustiva de los métodos de Object se puede consultar la documentación de la API del JDK.

La cláusula final

En ocasiones es conveniente que un método no sea redefinido en una clase derivada o incluso que una clase completa no pueda ser extendida. Para esto está la cláusula final, que tiene significados levemente distintos según se aplique a un dato miembro, a un método o a una clase.

Para una clase, final significa que la clase no puede extenderse. Es, por tanto el punto final de la cadena de clases derivadas. Por ejemplo si se quisiera impedir la extensión de la clase Ejecutivo, se pondría:

final class Ejecutivo {
. . .
}

Para un método, final significa que no puede redefinirse en una clase derivada. Por ejemplo si declaramos:

class Empleado {
. . .
public final void aumentarSueldo(int porcentaje) {
. . .
}
. . .
}

entonces la clase Ejecutivo, clase derivada de Empleado no podría reescribir el método aumentarSueldo, y por tanto cambiar su comportamiento.

Para un dato miembro, final significa también que no puede ser redefinido en una clase derivada, como para los métodos, pero además significa que su valor no puede ser cambiado en ningún sitio; es decir el modificador final sirve también para definir valores constantes. Por ejemplo:

class Circulo {
. . .
public final static float PI = 3.141592;
. . .
}

En el ejemplo se define el valor de PI como de tipo float, estático (es igual para todas las instancias), constante (modificador final) y de acceso público.

Herencia simple

Java incorpora un mecanismo de herencia simple. Es decir, una clase sólo puede tener una superclase directa de la cual hereda todos los datos y métodos. Puede existir una cadena de clases derivadas en que la clase A herede de B y B herede de C, pero no es posible escribir algo como:

class A extends B , C .... // error

Este mecanismo de herencia múltiple no existe en Java.

Java implanta otro mecanismo que resulta parecido al de herencia múltiple que es el de las interfaces que se verá más adelante.

lunes, 2 de agosto de 2010

Herencia en java

Herencia


Composición

En anteriores ejemplos se ha visto que una clase tiene datos miembro que son instancias de otras clases. Por ejemplo:

class Circulo {
Punto centro;
int radio;
float superficie() {
return 3.14 * radio * radio;
}
}

Esta técnica en la que una clase se compone o contiene instancias de otras clases se denomina composición. Es una técnica muy habitual cuando se diseñan clases. En el ejemplo diríamos que un Circulo tiene un Punto (centro) y un radio.

Herencia

Pero además de esta técnica de composición es posible pensar en casos en los que una clase es una extensión de otra. Es decir una clase es como otra y además tiene algún tipo de característica propia que la distingue. Por ejemplo podríamos pensar en la clase Empleado y definirla como:

class Empleado {
String nombre;
int numEmpleado , sueldo;

static private int contador = 0;

Empleado(String nombre, int sueldo) {
this.nombre = nombre;
this.sueldo = sueldo;
numEmpleado = ++contador;
}

public void aumentarSueldo(int porcentaje) {
sueldo += (int)(sueldo * aumento / 100);
}

public String toString() {
return "Num. empleado " + numEmpleado + " Nombre: " + nombre +
" Sueldo: " + sueldo;
}
}

En el ejemplo el Empleado se caracteriza por un nombre (String) y por un número de empleado y sueldo (enteros). La clase define un constructor que asigna los valores de nombre y sueldo y calcula el número de empleado a partir de un contador (variable estática que siempre irá aumentando), y dos métodos, uno para calcular el nuevo sueldo cuando se produce un aumento de sueldo (método aumentarSueldo) y un segundo que devuelve una representación de los datos del empleado en un String.(método toString).

Con esta representación podemos pensar en otra clase que reuna todas las características de Empleado y añada alguna propia. Por ejemplo, la clase Ejecutivo. A los objetos de esta clase se les podría aplicar todos los datos y métodos de la clase Empleado y añadir algunos, como por ejemplo el hecho de que un Ejecutivo tiene un presupuesto.

Así diriamos que la clase Ejecutivo extiende o hereda la clase Empleado. Esto en Java se hace con la clausula extends que se incorpora en la definición de la clase, de la siguiente forma:

class Ejecutivo extends Empleado {
int presupuesto;
void asignarPresupuesto(int p) {
presupuesto = p;
}
}

Con esta definición un Ejecutivo es un Empleado que además tiene algún rasgo distintivo propio. El cuerpo de la clase Ejecutivo incorpora sólo los miembros que son específicos de esta clase, pero implícitamente tiene todo lo que tiene la clase Empleado.

A Empleado se le llama clase base o superclase y a Ejecutivo clase derivada o subclase.

Los objetos de las clases derivadas se crean igual que los de la clase base y pueden acceder tanto sus datos y métodos como a los de la clase base. Por ejemplo:

Ejecutivo jefe = new Ejecutivo( "Armando Mucho", 1000);
jefe.asignarPresupuesto(1500);
jefe.aumentarSueldo(5);

Nota: La discusión acerca de los constructores la veremos un poco más adelante.

Atención!: Un Ejecutivo ES un Empleado, pero lo contrario no es cierto. Si escribimos:

Empleado curri = new Empleado ( "Esteban Comex Plota" , 100) ;
curri.asignarPresupuesto(5000); // error

se producirá un error de compilación pues en la clase Empleado no existe ningún método llamado asignarPresupuesto.

Redefinición de métodos. El uso de super.

Además se podría pensar en redefinir algunos métodos de la clase base pero haciendo que métodos con el mismo nombre y características se comporten de forma distinta. Por ejemplo podríamos pensar en rediseñar el método toString de la clase Empleado añadiendo las características propias de la clase Ejecutivo. Así se podría poner:

class Ejecutivo extends Empleado {
int presupuesto;

void asignarPresupuesto(int p) {
presupuesto = p;
}

public String toString() {
String s = super.toString();
s = s + " Presupuesto: " + presupuesto;
return s;
}
}

De esta forma cuando se invoque jefe.toString() se usará el método toString de la clase Ejecutivo en lugar del existente en la clase Empleado.

Observese en el ejemplo el uso de super, que representa referencia interna implícita a la clase base (superclase). Mediante super.toString() se invoca el método toString de la clase Empleado

Inicialización de clases derivadas

Cuando se crea un objeto de una clase derivada se crea implicitamente un objeto de la clase base que se inicializa con su constructor correspondiente. Si en la creación del objeto se usa el constructor no-args, entonces se produce una llamada implicita al constructor no-args para la clase base. Pero si se usan otros constructores es necesario invocarlos explicitamente.

En nuestro ejemplo dado que la clase método define un constructor, necesitaremos también un constructor para la clase Ejecutivo, que podemos completar así:

class Ejecutivo extends Empleado {
int presupuesto;

Ejecutivo (String n, int s) {
super(n,s);
}

void asignarPresupuesto(int p) {
presupuesto = p;
}

public String toString() {
String s = super.toString();
s = s + " Presupuesto: " + presupuesto;
return s;
}
}

Observese que el constructor de Ejecutivo invoca directamente al constructor de Empleado mediante super(argumentos). En caso de resultar necesaria la invocación al constructor de la superclase debe ser la primera sentencia del constructor de la subclase.

martes, 27 de julio de 2010

Bienvenidos!!!

Primera Clase 26 - 07 -2010 - Conceptos básicos de la 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.