¡Acceso ilimitado 24/7 a todos nuestros libros y vídeos! Descubra la Biblioteca Online ENI. Pulse aquí
¡Acceso ilimitado 24/7 a todos nuestros libros y vídeos! Descubra la Biblioteca Online ENI. Pulse aquí
  1. Libros
  2. Desarrollo informático
  3. Programación orientada a objetos
Extrait - Desarrollo informático Aprenda a diseñar antes de programar
Extractos del libro
Desarrollo informático Aprenda a diseñar antes de programar Volver a la página de compra del libro

Programación orientada a objetos - Introducción

Objetivos del capítulo

  1. Desarrollar en Java aplicaciones en programación orientada a objetos.

  2. Utilizar las nociones de clase, de miembros (propiedades y métodos).

  3. Instanciar los objetos.

  4. Utilizar la encapsulación.

  5. Utilizar los diagramas de clases UML para diseñar y representar las clases.

Clase, propiedades, referencia, instanciación

1. Clase Punto

La clase Punto tiene dos propiedades, x e y, de tipo int. La clase Punto y sus propiedades, x e y, van precedidas de la palabra clave public. Se utilizan por cualquier otra clase.

public class Punto  
{  
   public int x;  
   public int y;  
} 

2. Representación UML de la clase Punto

UML (Unified Modeling Language) es un lenguaje de modelización gráfica, basado en pictogramas. El siguiente esquema es una representación de la clase Punto en UML:

images/203-1.png
  • El rectángulo de la parte superior contiene el nombre de la clase.

  • El de en medio, contiene las propiedades de la clase. El + indica que la propiedad x es pública. El : va seguido del tipo de la propiedad.

  • El rectángulo de la parte inferior contiene los métodos de la clase. En este primer ejemplo, no hay.

3. Utilización de la clase Punto

a. Clase principal

VerificaPunto es la clase «principal» de la aplicación, la que tiene el método main().

public class VerificaPunto  
{  
   public static void main(String argv[])  
   {  
       Punto p;  
  
       p = new Punto();  
       System.out.println("Referencia del objeto Punto (p): " + p);  ...

Encapsulación

1. La palabra clave private

La encapsulación consiste en asignar la palabra clave private a las propiedades de la clase.

public class Punto  
{ 
   private int x;   
   private int y;  
} 

En el diagrama UML se ha utilizado el signo - para preceder a cada propiedad.

images/203-3.png

Una propiedad privada solo se puede usar en el interior de su clase.

El compilador se da cuenta inmediatamente, indicando un error por cada utilización de x e y en la clase VerificaPunto:

images/203-F0.png

La encapsulación, aunque muy sencilla de implementar, es una noción fundamental de la programación orientada a objetos. Es una guía muy eficaz para programar correctamente y situar los tratamientos en la clase apropiada, como vamos a comprobar en nuestro ejemplo.

Eliminar la palabra clave private de una propiedad para satisfacer al compilador es una mala idea. Es, en general, síntoma de un mal diseño. Por defecto, en todo el libro las propiedades se declaran private.

2. Métodos de instancia

a. Clase principal

El método main() de la clase VerificaPunto no puede acceder a las propiedades de la clase Punto porque se declaran en private. Para acceder a las propiedades private de un objeto Punto, hay que pasar por los métodos public de la clase Punto.

El método muestraXY() muestra los valores de las propiedades del objeto (de la instancia) que le llama. Se llama método de instancia.

De la misma manera, el método de instancia modificaXY() modifica las propiedades...

Trabajo práctico: clase Empleado

1. Objetivo

Aplicar las nociones estudiadas:

  • Clase.

  • Propiedades.

  • Métodos.

  • Instancias, objetos.

2. Tema

Se proporciona la clase principal de la aplicación:

public class VerificaEmpleado  
{  
   public static void main(String argv[])  
   {  
       Empleado e;  
       String nombre;  
       int matricula;  
  
       e = new Empleado();  
       e.muestraEmpleado();  
  
       System.out.print("\nDespués de cambio de nombre:\n");  
       nombre = "BUITRE LEONADO";  
       e.setNombre(nombre);  
       e.muestraEmpleado();  
  
       System.out.print("\nDespués de cambio de matrícula:\n");  
       matricula = 17;  
       e.setMatricula(matricula);  
       e.muestraEmpleado();  
   }  
}   

La visualización obtenida durante la ejecución es la siguiente:

images/203-8.png

3. Trabajo

Escribir la clase Empleado, que tenga dos propiedades: matricula (int), nombre...

Constructor

1. Clase Punto

Durante la instanciación de un objeto, se llama sistemáticamente un método particular llamado constructor.

Este método lleva el nombre de la clase (por lo tanto, es el único cuyo nombre comienza por una mayúscula). No está tipado (sin void ni tipo de retorno).

En la clase Punto, no hemos escrito constructor. En este caso, justo después de la instanciación, la máquina virtual ejecuta un constructor por defecto cuyo código es:

public Punto()  
{  
} 

Este método no hace nada…

Es posible escribir nuestro propio constructor. Esto solo es interesante si contiene código. 

Ejemplo

Tan pronto como se produce la instanciación, queremos inicializar x e y con valores diferentes de 0. Es posible escribir un constructor que reciba dos argumentos:

public class Punto  
{  
  
. . .  
  
// -------------------------------------------------------------------- 
// Constructor  
// -------------------------------------------------------------------- 
public Punto(int x, int y)  
{  
   this.x = x;  
   this.y = y;  
}  
  
. . .  
  
} 

2. Clase principal

La instanciación de dos objetos p1 y p2 se hace con el nuevo constructor:

public...

Sobrecarga de métodos - Sobredefinición

1. Clase Punto

El lenguaje Java permite la sobrecarga de los métodos. Dentro de una misma clase, es posible crear varios métodos que tengan el mismo nombre. Por supuesto, la máquina virtual debe poder distinguirlos para poder encontrar y ejecutar el correcto. Deben tener una lista de argumentos diferente (en número o en tipo).

Este tipo de sobrecarga se llama sobredefinición.

public class Punto  
{  
   . . .  
  
   public Punto()  
   {  
   }  
  
   public Punto(int x, int y)  
   {  
      this.x = x;  
      this.y = y;  
   }  
     
   . . .  
  
   public void reinit()  
   {  
      this.x = 0;  
      this.y = 0;  
   }   
   public void reinit(int x, int y)  
   {  
      this.x = x;  
      this.y = y;  
   }  
} 

La clase Punto tiene dos constructores y dos métodos llamados reinit().

2. Clase principal

public...

Primer enfoque de la herencia - Sobrecarga - Redefinición

1. La herencia

Todas las clases heredan de la clase Object (paquete java.lang de la API Java).

De esta manera, es posible esquematizar la clase Punto en el siguiente diagrama de clases:

images/203-12.png

Se trata aquí de una jerarquía sencilla: en la parte superior, la clase «madre»; en la parte inferior, la clase «hija» (de la que hereda).

Por herencia, la clase Punto tiene, además de sus propiedades x e y, todas las propiedades de la clase Object. También tiene todos los métodos de la clase object.

Es posible utilizar todos los métodos de la clase Object a partir de la referencia de un objeto Punto. El siguiente programa ilustra esta posibilidad: el método toString() de la clase Object devuelve una cadena de caracteres compuesta por el nombre de la clase y el valor de la referencia escrito en hexadecimal, separados por el carácter @. Su firma es: public String toString().

public class VerificaPunto  
{  
   public static void main(String argv[])  
   {  
       Punto p;  
  
       p = new Punto(7, 17);  
       System.out.println(p.toString());  
   }  
} 

El resultado de la ejecución de este programa es el siguiente:

images/203-13.png

Cuando el método...

Propiedades de instancia, propiedades de clase

1. Declaración

Las propiedades utilizadas en los ejemplos anteriores son propiedades de instancia. Se asignan en memoria durante cada instanciación (para cada new). Hay tantas como objetos creados.

Es posible declarar propiedades de clase, asignadas en memoria una única vez, tan pronto como se produce el lanzamiento de la ejecución del programa. Una propiedad de clase se declara con la palabra clave static.

Ejemplo

public class Punto  
{  
   private int x;  
   private int y;  
   private static int numeroPuntos;  
  
   . . .  
} 

2. Diseño

Cuando se diseña una clase, para cada propiedad hay que se plantearse las siguientes preguntas:

  • Esta propiedad ¿está presente una vez por objeto? Si la respuesta es sí, es una propiedad no static, una propiedad de instancia; cada objeto tiene la suya. Ejemplo: las coordenadas x e y de un punto.

  • Esta propiedad ¿es única para la clase? Si la respuesta es sí, es una propiedad static, una propiedad de clase. Ejemplo: el contador del número de puntos instanciados (numeroPuntos).

Métodos de instancia, métodos de clase

Un método de instancia es llamado por un objeto (una referencia de objeto). Ejemplo: p.muestraXY().

Un método de instancia solo es realmente interesante si su resultado varía en función del objeto; por lo tanto si utiliza propiedades del objeto. En general, este será el caso, incluso si esto no es obligatorio.

Un método de clase se llama a partir del nombre de la clase y no hace necesaria la creación de un objeto. Ejemplo: Teclado.readString(). Un método de clase se declara con la palabra clave static.

Dado que un método de clase se puede utilizar sin instanciación,se excluye que use propiedades de instancia. Un método static solo puede utilizar las propiedades static.

1. Ejemplo: clase Punto

Para contar el número de objetos Punto creados, hay que incrementar el contador numeroPuntos en cada constructor. Un método static getNumeroPuntos() permite devolver el valor del contador.

public class Punto  
{  
   private int x;  
   private int y;  
   private static int numeroPuntos;  
  
   public Punto()  
   {  
      numeroPuntos++;  
   }  
  
   public Punto(int x, int y)  
   {  
      this.x = x;  
      this.y = y;  
      numeroPuntos++;  
   }  
  
   . . .  
  
   public static int getNumeroPuntos()  
   {  ...

Constructores y métodos ‘private’

En todos los ejemplos anteriores, hemos elegido declarar las propiedades private para respetar la encapsulación. En contraposición, todos los métodos se han declarado como public.

Respetamos este diseño a lo largo del libro.

Por supuesto, puede ser interesante eliminar esta regla de manera excepcional. Un método se puede declarar private. En este caso, su uso estará limitado al resto de los métodos de la misma clase. El siguiente ejemplo muestra el interés de la declaración de un constructor como private.

1. Clase Conejo

El diseñador de la clase Conejo ha decidido limitar el número de instanciaciones posibles de objetos Conejo. Para esto, el constructor se declara como private. Esta declaración impide cualquier instanciación fuera de la clase Conejo. Para permitir a otra clase instanciar un Conejo, ponemos a su disposición un método public crearConejo(), dentro del cual se realiza el control de los nacimientos:

numero: número de conejos creados.

numeroMaxi: número máximo de conejos.

public class Conejo  
{  
   private static int numero = 0;  
   private static int numeromaxi = 5; 
  
   private Conejo()  
   {  
       numero++;  
   } ...

Garbage collector

La siguiente aplicación crea dos instancias de Punto. Las referencias de los dos objetos se almacenan en la misma referencia:

public class VerificaPunto7  
{  
   public static void main(String argv[])  
   {  
       Punto p;  
  
       p = new Punto();  
       System.out.println("p: " + p);  

A causa de la nueva instanciación del objeto p, el objeto referenciado anteriormente por p ya no es accesible porque su dirección se ha eliminado. El espacio perdido se recupera automáticamente por el «garbage collector».

       p = new Punto();  
       System.out.println("p: " + p);  
   }  
} 

A continuación se muestra el resultado de la ejecución de este programa:

images/203-18.png

El garbage collector es un programa que funciona de forma automática y que libera el espacio ocupado inútilmente.

Trabajo práctico: clase Empleado (segunda versión)

1. Objetivo

Se trata de aplicar el conjunto de las nociones estudiadas:

  • Clase.

  • Propiedades.

  • Métodos.

  • Instancias, objetos.

  • Constructores.

  • Sobrecargas (sobredefinición).

  • toString() (redefinición).

2. Tema

Se proporciona la clase principal de la aplicación:

import java.io.*;  
import herramientasMG.varias.*;  
  
public class VerificaEmpleado  
{  
   public static void main(String argv[]) throws IOException  
   {  
       Empleado e1, e2, e3;  
       String nombre;  
  
       e1 = new Empleado("MIRLO");  
       System.out.println(e1);  
  
       e2 = new Empleado(12, "COLIBRÍ");  
       System.out.println("\n" + e2);  
  
       e3 = new Empleado("BUITRE");  
       System.out.println("\n" + e3);  
  
       System.out.println("\nNúmero de empleados creados: " +  
               Empleado.getContador());  
       System.out.println("Siguiente...

Trabajo práctico: coches

1. Objetivo

Se trata de desarrollar varias clases relacionadas entre ellas.

2. Tema

Se proporciona la siguiente clase principal:

public class VerificaCoche  
{  
   public static void main(String argv[])  
   {  
       Garaje g1, g2;  
       Vendedor vendedor1, vendedor2, vendedor3;  
       Coche v1, v2, v3, v4;  
  
// --------------------------------------------------------------------------  
// Creación y visualización de los garajes  
// --------------------------------------------------------------------------  
       System.out.println("LISTA DE LOS GARAJES DE LA MARCA "  
           + Garaje.getNombreMarca() + "\n");  
  
       g1 = new Garaje("Avenida de los Campos Elíseos 75008 PARÍS");  
       g2 = new Garaje();  
  
       System.out.println(g1);  
       System.out.println(g2);  
  
// --------------------------------------------------------------------------  
// Creación y visualización de los vendedores  
// --------------------------------------------------------------------------  
       vendedor1 = new Vendedor(“Común”, "GANSO", g1);  
       vendedor2 = new Vendedor("Águila", "REAL", g2);  
       vendedor3 = new Vendedor("Quebrantahuesos", "PESCADOR", g1);  
  
       System.out.println("\n\nLISTA DE LOS VENDEDORES");  
       System.out.println(vendedor1);  
       System.out.println(vendedor2);  
       System.out.println(vendedor3);  
  
// --------------------------------------------------------------------------  
// Creación y visualización de los coches:  
// --------------------------------------------------------------------------  ...