Java: El concepto de clase

lasecreObjetivo: presentar el concepto de clase, pilar sobre el que está construido todo el paradigma de la programación orientada a objetos.

Voy a proponerte un sencillo juego. Sal a la calle, mira a tu alrededor y contempla el mundo de un modo particular.

Veo veo… ¿Qué ves?
Una cosita… ¿Y qué cosita es?

Para empezar, quiero que identifiques qué tipos de objetos ves…

Puedes, por ejemplo, encontrarte coches, bares, semáforos o personas, por citar sólo unos cuantos tipos. Date cuenta de que, cuando digo tipos de objetos, hablo de un modo conceptual y general. Si te resulta chocante referirte a una persona como un objeto, prueba a sustituir la expresión por tipos de entidades, en su lugar.

Tipo y clase son dos términos sinónimos, de modo que vamos a cambiar “tipos de objetos” por “clases de objetos”, aproximándonos un poco más al concepto que da pie al artículo de hoy.

¿Qué clases de objetos vemos? Coches, bares, semáforos, personas…

La siguiente transformación lingüística consiste en simplificar clases de objetos por simplemente clases:

¿Qué clases vemos? Coches, bares, semáforos, personas…

Y ahora sí, nos sumergimos plenamente en la terminología de la programación orientada a objetos:

Tenemos la clase Coche, la clase Bar, la clase Semáforo, la clase Persona

Poco interesan ahora los detalles concretos. No importa si esa persona es Marta, está en el bar “Casa Manolo”, si tiene un Seat Panda o si el semáforo está en rojo. Estamos pensando en términos clasificatorios.

Vamos a adentrarnos ahora en el interior de cada una de estas clases.

¿Cómo son los coches? ¿Qué características pueden diferenciar uno de otro?

Por ejemplo, podríamos indicar la marca, el modelo, el color, la cilindrada, etc.

A las características las vamos a denominar atributos, término muy utilizado en la programación orientada a objetos.

¿Qué atributos tiene la clase Bar?

Todo bar tiene un nombre, una ubicación, un estado (si está abierto o cerrado), una lista de precios,…

Como atributos de la clase Semáforo podríamos indicar su ubicación y estado (rojo, verde o ámbar).

La clase Persona podría definir como atributos el nombre, sexo, edad, estado civil, altura, etc.

A continuación pensemos en el comportamiento de estas clases. Preguntémonos qué cosas hacen, qué tipo de acciones pueden realizar.

Un coche puede arrancar, detenerse, girar a la izquierda, acelerar, frenar, encender sus luces. Un semáforo puede cambiar de estado. Un bar puede abrir, cerrar, servirte una cerveza, cobrarla, modificar la lista de precios. Una persona puede hablar, dormir, conducir un coche, tomarse una cerveza en un bar.

En terminología de la programación orientada a objetos, a estas funciones que determinan el comportamiento de una clase se las conoce como métodos.

Sabemos lo que es una clase y que está compuesta de atributos y métodos. Nuestra labor ahora consistirá en modelar en Java estas clases.

Modelar no es otra cosa sino crear una abstracción que represente de algún modo una determinada realidad.

Para crear en Java la clase Coche procederíamos del siguiente modo:

class Coche
{
}

Entre las llaves introduciremos los atributos y métodos de que consta la clase. Observa el uso de la palabra reservada class.

El nombre Coche lo escribimos con la primera letra en mayúsculas, pues es de común acuerdo entre los programadores en Java que los nombres de clases empiecen así.

Introduzcamos algunos atributos:

class Coche
{
  String marca;
  String modelo;
  String color;
  int numeroDePuertas;
  int cuentaKilometros;
  int velocidad;
  boolean arrancado;
}

Declarar atributos es algo similar a declarar una variable normal. El nombre del atributo se precede por su tipo. Así, en el ejemplo, tenemos tres atributos de tipo String que contendrán cadenas de caracteres; otros tres de tipo int para almacenar valores enteros; finalmente, el atributo arrancado, que utilizaremos para indicar si el coche está en marcha o no, es de tipo boolean, admitiendo como posibles valores true o false.

Los tipos int y boolean forman parte de los tipos básicos de Java, conocidos como tipos primitivos. Los presentaremos formalmente a su debido momento; por ahora es suficiente con que conozcas su existencia y cómo los utilizamos.

El tipo String, que escribimos con la primera letra en mayúsculas (lo que debería darte una pista), no es más que otra clase, como lo son las clases Coche y Persona. Es una clase muy importante en Java que encapsula un buen conjunto de métodos para trabajar con cadenas de caracteres.

El concepto importante que debes entender es que los atributos no necesariamente son siempre de tipos básicos, sino que también pueden ser de cualquier clase, incluso de una propia que nosotros mismos hayamos creado.

Por ejemplo, podríamos definir un nuevo atributo de la clase Coche, llamado conductor, en el que figure la persona (de tipo Persona) que lo conduce:

Persona conductor;

Fíjate también en la convención utilizada para nombres de variables compuestos de varias palabras. Se escriben todas juntas, pero iniciando cada palabra en mayúsculas, a excepción de la primera. Esto forma parte también del estilo de escritura Java. Es opcional, naturalmente.

Eso sí, ten siempre presente que Java distingue mayúsculas de minúsculas. No es lo mismo numeroDePuertas que numerodepuertas.

Definamos ahora los métodos de la clase Coche:


class Coche
{
  String marca;
  String modelo;
  String color;
  int numeroDePuertas;
  int cuentaKilometros;
  int velocidad;
  boolean arrancado;
  
  void arrancar()
  {
  }
  
  void parar()
  {
  }
  
  void acelerar()
  {
  }
  
  void frenar()
  {
  }

  void pitar()
  {
  }

  int consultarCuentaKilometros()
  {
  }
}

Vamos a comentar esto con cuidado…

El nombre de método viene seguido por un par de paréntesis, pues en ocasiones los métodos podrán recibir argumentos que luego se utilizarán en el cuerpo del método. Aunque el método no requiera argumentos los paréntesis son absolutamente necesarios.

Por otro lado, el nombre del método va precedido por el tipo del valor que devuelve. Hay que indicarlo incluso si el método no devuelve explicitamente ningún valor. Ese caso se indica con el tipo void.

Entre el par de llaves { } introduciremos el cuerpo del método, las instrucciones que indican su operatividad.

Escribamos algo de código básico en cada uno de ellos:

class Coche
{
  String marca;
  String modelo;
  String color;
  int numeroDePuertas;
  int cuentaKilometros;
  int velocidad;
  boolean arrancado;
  
  void arrancar()
  {
    arrancado = true;
  }
  
  void parar()
  {
    arrancado = false;
  }
  
  void acelerar()
  {
    velocidad = velocidad + 1;
  }
  
  void frenar()
  {
    velocidad = velocidad - 1;
  }
  
  void pitar()
  {
    System.out.println("Piiiiiiiiiiiiiiiiii");
  }

  int consultarCuentaKilometros()
  {
    return cuentaKilometros;
  }
}

Es prácticamente autoexplicativo: los métodos arrancar() y parar() establecen el atributo booleano arrancado a true y false, respectivamente. Los métodos acelerar() y frenar() incrementan y decrementan en una unidad, respectivamente, el atributo velocidad. El método pitar() imprime en consola una cadena de caracteres. El método consultarCuentaKilometros() devuelve a quien lo invoca (fíjate en el return) lo que contiene el atributo cuentaKilometros. Observa que es el único que devuelve explícitamente un valor (de tipo entero); los restantes, aunque algunos modifican los atributos de la misma clase, no devuelven ningún valor a quien los llama.

Podríamos modelar la clase Persona del siguiente modo:

class Persona
{
  char sexo;
  String nombre;
  int edad;
  Coche coche;   // El coche que conduce esa persona
  
  void saludar()
  {
    System.out.println("Hola, me llamo " + nombre);
  }
  
  void dormir()
  {
    System.out.println("Zzzzzzzzzzz");
  }
  
  int obtenerEdad()
  {
    return edad;
  }
}

Fíjate que uno de los atributos es precisamente de la clase Coche que acabamos de definir:

Coche coche;

No confundas el nombre del atributo (coche, en minúsculas), con el nombre de la clase (Coche, con la primera en mayúsculas). Recuerda, nuevamente, que para Java son identificadore distintos.

Te propongo como ejercicio que te entretengas modelando las otras clases, u otras de tu elección, para asentar estos conceptos.

Las entidades no tienen por qué ser tangibles, necesariamente. El siguiente código modela nuestras emociones:

class Emocion
{
  String emocion;
  
  String obtenerEmocion()
  {
    return emocion;
  }
  
  void cambiarEmocion(String nuevaEmocion)
  {
    emocion = nuevaEmocion;
  }
}

El método obtenerEmocion() devuelve a quien lo invoca la cadena de caracteres referenciada en el atributo emocion. El método cambiarEmocion(), que requiere como argumento una cadena de caracteres, se ocupa de modificar el atributo con el argumento facilitado.

Lo verdaderamente importante es que comprendas el concepto de clase. No te preocupes si te resultan quizás algo oscuros algunos de los ejemplos; oportunamente profundizaremos en todas estas cuestiones.

¿Qué hacemos con nuestras flamantes clases recien creadas?

Típicamente las almacenaremos, cada una, en su propio fichero .java.

Créate una carpeta común y vuelca en ella los ficheros Coche.java, Persona.java y Emocion.java.

Podemos compilarlas, todas a la vez, del siguiente modo:

javac *.java

Obteniendo, si no hay errores, los ficheros Coche.class, Persona.class y Emocion.class.

En el próximo artículo utilizaremos estas clases, momento en el que introduciremos otro concepto esencial, el de objeto.

Javier Montero Gabarró


Java: El concepto de clase


El texto de este artículo se encuentra sometido a una licencia Creative Commons del tipo CC-BY-NC-ND (reconocimiento, no comercial, sin obra derivada, 3.0 unported)


El Club del Autodidacta


Índice completo de artículos sobre Java.

Deja un comentario