miércoles, 18 de junio de 2008

Clases y Objetos

Hola, dentro de las clases y presentaciones que expongo donde trabajo, he planificado la preparacion de estos documentos con el objetivo de introducir a los oyentes al mundo Java, SOA, y UML.
Traspasandoles mi conocimiento para un mejor entendimiento de las tecnologìas que demanda la Industria.
Las presentaciones de UML y Java apuntan a eso. Ahora veremos un articulo sobre Clases y Objetos, tema presentado en esta planificacion.

Comencemos.

Programa Java
  • Un programa Java está formado por un conjunto de clases que interactúan entre sí
  • La clase es la unidad básica de programación
Clase
Implementación de un tipo de dato.
Una clase sirve tanto de módulo como de tipo
  • Tipo: Descripción de un conjunto de objetos (equipados con ciertas operaciones).
  • Módulo: Unidad de descomposición del software.
Objeto
Instancia de una clase:
Unidad que encapsula estado y comportamiento.
  • Un objeto puede caracterizar una entidad física (un teléfono, un interruptor, un cliente) o una entidad abstracta (un número, una fecha, una ecuación matemática).
  • Todos los objetos son instancias de una clase: Los objetos se crean por instanciación de las clases.
  • Todos los objetos de una misma clase (p.ej. coches) comparten ciertas características: sus atributos (tamaño, peso, color, potencia del motor...) y el comportamiento que exhiben (aceleran, frenan, curvan...).
Todo objeto tiene...
- Identidad (puede distinguirse de otros objetos)
- Estado (datos asociados a él)
- Comportamiento (puede hacer cosas)

Las diferentes instancias de cada clase difieren entre sí por los valores de los datos que encapsulan (sus atributos).
Dos objetos con los mismos valores en sus atributos pueden ser diferentes.
TODOS los objetos de una misma clase usan el mismo algoritmo como respuesta a mensajes similares.
El algoritmo empleado como respuesta a un mensaje (esto es, el método invocado) viene determinado por la clase del receptor.

Clase
Una clase es una descripción de un conjunto de objetos similares.
Al programar, definimos una clase para especificar cómo se comportan y mantienen su estado los objetos de esa clase.
A partir de la definición de la clase, se crean tantos objetos de esa clase como nos haga falta

Cada clase en Java:
• Se define en un fichero independiente con extensión .java.
• Se carga en memoria cuando se necesita.

La máquina virtual Java determina en cada momento las clases necesarias para la aplicación y las carga en memoria.

El programa puede ampliarse dinámicamente (sin tener que recompilar):

La aplicación no es un bloque monolítico de código.
Para definir una clase en Java se utiliza la palabra reservada class, seguida del nombre de la clase (un identificador):

public class MiClase { ... }

NOTA: Es necesario que indiquemos el modificador de acceso public para que podamos usar nuestra clase “desde el exterior”.

El nombre de una clase debe ser un identificador válido en Java.
Por convención, los identificadores que se les asignan a las clases en Java comienzan con mayúscula.
En Java, las clases públicas deben estar definidas en ficheros con extensión .java cuyo nombre coincida exactamente con el identificador asignado a la clase.

Errores comunes
Cuando el nombre de la clase no coincide con el nombre del fichero, el compilador nos da el siguiente error:

Public class MiClase must be defined in a file called MiClase.java

donde MiClase es el nombre de nuestra clase.
Las llaves siempre deben ir en parejas: Si falta la llave de cierre } el compilador da un error:

‘}’ expected Lo mismo ocurre si se nos olvida abrir la llave ({): ‘{’ expected


Encapsulación de datos (variables) y operaciones (métodos)

Objeto = Identidad + Estado + Comportamiento


Identidad
La identidad de un objeto lo identifica unívocamente:
- Es independiente de su estado.
- No cambia durante la vida del objeto.

Estado
El estado de un objeto viene dado por los valores de sus atributos.
- Cada atributo toma un valor en un dominio concreto.
- El estado de un objeto evoluciona con el tiempo
- Los atributos de un objeto no deberían ser manipulables
directamente por el resto de objetos del sistema (ocultamiento de
información):
o Se protegen los datos de accesos indebidos.
o Se distingue entre interfaz e implementación.
o Se facilita el mantenimiento del sistema.


Interfaz vs. implementación
Los objetos se comunican a través de interfaces bien definidas sin tener que conocer los detalles internos de implementación de los demás objetos.

Ejemplo: Un coche se puede conducir...
  • Sin saber exactamente de qué partes consta el motor ni cómo funciona éste (implementación).
  • Basta con saber manejar el volante, el acelerador y el freno (interfaz).

Comportamiento de Objetos

Los métodos que definen el comportamiento de un objeto:
- Agrupan las competencias del objeto (responsabilidades)
- Describen sus acciones y reacciones.

Las acciones realizadas por un objeto son consecuencia directa de un estímulo externo (un mensaje enviado desde otro objeto) y dependen del estado del objeto.
El interfaz de un objeto ha de establecer un contrato, un conjunto de condiciones precisas que gobiernan las relaciones entre una clase proveedora y sus clientes (diseño por contrato).

Estado y comportamiento están relacionados.

Ejemplo
Un avión no puede aterrizar (acción) si no está en vuelo (estado)

Representacion Grafica de Una Clase
Una clase se representa con un rectángulo dividido en tres partes:
- El nombre de la clase (identifica la clase de forma unívoca)
- Sus atributos (datos asociados a los objetos de la clase)
- Sus operaciones (comportamiento de los objetos de esa clase)

IMPORTANTE: Las clases se deben identificar con un nombre que, por lo general, pertenecerá al vocabulario utilizado habitualmente al hablar del problema que tratamos de resolver.
Declaración en Java de una clase.

public class Cuenta { ... }
Representación de una clase con sus atributos:

public class Cuenta
{
private double balance; // Saldo
private double limit; // Límite
...
}
public class Cuenta
{
private double balance = 0;
private double limit;
...
}

NOTA:
Aquí hemos decidido utilizar el tipo primitivo double para representar cantidades de dinero. En un programa en el que no se pudiesen permitir errores de redondeo en los cálculos, deberíamos utilizar otro tipo más adecuado (por ejemplo, BigDecimal).


Representación de las operaciones de una clase:

public class Cuenta
{
private double balance = 0;
private double limit;
public void ingresar (...) ...
public void retirar (...) ...
}

Los métodos implementan en Java las operaciones características de los objetos de una clase concreta.

public class Cuenta
{
private double balance = 0;
private double limit;
public void ingresar (double cantidad)
{
balance = balance + cantidad;
}
public void retirar (double cantidad)
{
balance = balance – cantidad;
}
}


Representación gráfica en UML:


Definición en Java:

Fichero Motocicleta.java

public class Motocicleta
{
// Atributos (variables de instancia)
private String matricula; // Placa de matrícula
private String color; // Color de la pintura
private int velocidad; // Velocidad actual (km/h)
private boolean en_marcha; // ¿moto arrancada?
// Operaciones (métodos)
public void arrancar ()
{ ... }
public void acelerar ()
{ ... }
public void frenar ()
{ ... }
public void girar (float angulo)
{ ... }
}



Uso de Objetos
El operador . (punto) en Java nos permite acceder a los distintos metodos de una clase:

objeto.metodo

Cuando tenemos un objeto de un tipo determinado y queremos acceder a uno de sus metodos sólo tenemos que poner el identificador asociado al objeto (esto es, el identificador de una de las variables de nuestro programa) seguido por un punto y por el identificador que hace referencia a un metodo concreto de la clase a la que pertenece el objeto.

¿Cómo se comprueba el estado de un objeto?
Accediendo a las variables de instancia del objeto

objeto.atributo

Por ejemplo, cuenta.balance nos permitiría acceder al valor numérico correspondiente al saldo de una cuenta, siempre y cuando cuenta fuese una instancia de la clase Cuenta.

¿Cómo se le envía un mensaje a un objeto?
Invocando a uno de sus métodos.

objeto.método(lista de parámetros)

La llamada al método hace que el objeto realice la tarea especificada en la implementación del método, tal como esté definida en la definición de la clase a la que pertenece el objeto.
Ejemplo

cuenta.ingresar(150.00);

Si cuenta es el identificador asociado a una variable de tipo Cuenta, se invoca al método ingresar definido en la clase Cuenta para depositar una cantidad de dinero en la cuenta.
La implementación del método ingresar se encarga de actualizar el saldo de la cuenta, sin que nosotros nos tengamos que preocupar de cómo se realiza esta operación.

Creacion de Objetos
Antes de poder usar un objeto hemos de crearlo...

El operador new nos permite crear objetos en Java.

Tipo identificador = new Tipo();

Si escribimos un programa como el siguiente:

public class Ingreso {
public static void main (String args[])
{
Cuenta cuenta; // Error
cuenta.ingresar(100.00);
}

}

El compilador nos da el siguiente error:
Ingreso.java:7:
variable cuenta might not have been initialized
cuenta.ingresar(100.00);
^
Hemos declarado una variable que, inicialmente, no tiene ningún valor.
Antes de utilizarla, deberíamos haberla inicializado (con un objeto del tipo adecuado):

Cuenta cuenta = new Cuenta();


Constructores
Cuando utilizamos el operador new acompañado del nombre de una clase, se crea un objeto del tipo especificado (una instancia de la clase cuyo nombre aparece al lado de new).
Al crear un objeto de una clase concreta, se invoca a un método especial de esa clase, denominado constructor, que es el que se encarga de inicializar el estado del objeto.

Constructor por defecto
Por defecto, Java crea automáticamente un constructor sin parámetros para cualquier clase que definamos.

public class Cuenta {
// Constante
public static final double LIMITE_NORMAL = 300.00;
// Variables de instancia

private double balance = 0;

private double limit = LIMITE_NORMAL;

// Métodos
...
}

Al crear un objeto de tipo Cuenta con new Cuenta(), se llama al constructor por defecto de la clase Cuenta, con lo cual se crea un objeto de tipo Cuenta cuyo estado inicial será el indicado en la inicialización de las variables de instancia balance y limit.


PrimerPrograma.java

/** * Este programa en Java imprime un saludo por pantalla. */
import java.*;


/* La clase principal se denomina PrimerPrograma */
public class PrimerPrograma {
public static void main(String args[ ]){
System.out.println("Hola Mundo ");
}
}

Herencia
Supongamos que tenemos una clase que nos define una persona.
Queremos las clases Alumno y Profesor.
Ambos son personas y seria perfecto no tener que volver a escribir (y pensar) todas las variables y funciones que ya hay en la clase Persona.



Ejemplo de Herencia


public class Persona {
protected int dni;
protected String nombre;
protected String direccion;
protected int telefono;
public int obtenerDni() {
return dni;
}
public void modificarDni(int dni) {
this.dni=dni;
}
public void mostrarPorPantalla() {
System.out.println("DNI: "+dni);
System.out.println("Nombre: "+nombre);
System.out.println("Direccion: "+direccion);
System.out.println("Telefono: "+telefono);
}
}


public class Alumno extends Persona {
protected int[ ] notas;
public void nuevaNota(int nota) {
// Añade una nueva nota
}
public void listadoNotas() {
System.out.println("Notas:");
for(int i=0;i
System.out.println(notas[i]);
}
}
public void mostrarPorPantalla() {
super.mostrarPorPantalla();
listadoNotas();
}
}

  • Java sólo tiene herencia simple. Esto es, una clase sólo puede heredar de una clase.
  • Además, si una clase no hacemos que herede de alguna otra clase, Java automáticamente hace que herede de la clase Object.

Bueno, eso seria por hoy.

Saludos y Suerte !!

2 comentarios:

Fantômas dijo...

Buen blog che! Te invito a darte una vuelta por el mío, creo que te puede llegar a interesar por las cosas que veo que posteás.

therooter.blogspot.com

Un abrazo.

rafero dijo...

Buena información la que publicas :)