Las clases son uno de los elementos principales de la programación orientada a objetos. Como Java es un lenguaje especialmente diseñado para trabajar con objetos, podemos decir que las clases son el elemento más importante en Java. El propio motor inicial de java («main») es una clase.
Cuando creamos un objeto de una clase, decimos que lo estamos instanciando. En ese momento, estamos dotando al objeto de unos atributos propios de la clase. También le estamos facilitando unos métodos característicos de dicha clase. Si estos métodos los definimos como static, podrán ser utilizados también fuera de la clase (son los métodos comparables con las funciones de otros lenguajes de programación). En caso contrario serán métodos reservados para los objetos de la clase. Las clases se suelen definir con la primera letra en mayúsculas y el resto en minúsculas.
Podemos crear una clase que contenga una serie de métodos, todos static que estén relacionados entre sí por un mismo tema o propósito. Este archivo de métodos podrá utilizarse como parte de cualquier otra programa java.
Por lo tanto podemos decir que los atributos de un objeto son los valores o
propiedades que tiene dicho objeto. Los métodos serían las acciones que pueden actuar sobre los atributos del objeto.
Para empezar podemos definir la clase “Libro”. Las clases se deben de guardar en un archivo cuyo nombre será el nombre de la clase que contiene.
public class Libro {
private String tema;
private int paginas;
private String editorial;
private int cantidad;
private String existencias;
private double precio;
public Libro(String tema, int paginas, String editorial) {
this.tema = tema;
this.paginas = paginas;
this.editorial = editorial;
}
public void ejemplares(int cantidad){
this.cantidad=cantidad;
if (cantidad>20){
this.existencias="muchas";
}
else if (cantidad>10){
this.existencias="algunas";
}
else if (cantidad>0) {
this.existencias = "pocas";
}
else {
this.existencias="agotado";
}
}
public void neto(double inicial, double iva, double descuento) {
double bruto = inicial + (inicial * iva / 100);
precio = bruto - (bruto * descuento / 100);
}
public String toString(){
String cadena=("Mi libro de "+tema+" tiene "+paginas+" páginas.");
return cadena;
}
}En la clase Libro hemos creado varios atributos y les hemos dado nombre.
A continuación establecemos el método Libro que será el constructor de la clase. Todos los objetos serán creados a partir de este método, que recibirá los argumentos temas, páginas y editorial. Es obligado que este método constructor tenga el mismo nombre que la clase (y el archivo).
Si no indicamos ningún constructor, java establece uno por defecto, pero crea el objeto en blanco y sin ningún tipo de atributos asociado. Lo recomendado es que nosotros establezcamos nuestro propio constructor.
Después viene el método ejemplares que recibe el argumento cantidad. Este argumento pasará a ser también atributo del objeto. Según el valor de cantidad, este mismo método nos crea el atributo existencias.
Mediante el método neto damos valor al atributo del objeto precio.
Por último tenemos el método toString( ), que nos permite generar una cadena de texto a partir un determinado objeto de la clase. Este método de creación de cadenas (a partir de un objeto) puede crearse en cualquier clase y para cualquier objeto, pero debe de tener este nombre.
public class Prueba3 {
public static void main(String[] args) {
Libro milibro=new Libro("Historia",254,"Ed.Libraco");
System.out.println("Mi libro de "+milibro.tema +" tiene "+milibro.paginas+ " páginas.");
System.out.println("La editorial es "+milibro.editorial+".");
milibro.ejemplares(18);
System.out.println("Actualmente hay "+milibro.existencias+" existencias.");
milibro.neto(20,7,2);
System.out.println(milibro);
}
}Teniendo en cuenta el código anterior, y siempre y cuando la clase Libro se encuentre en un archivo situado en la misma carpeta o directorio que dicho código, el resultado será el siguiente:
Resultado:
Mi libro de Historia tiene 254 páginas.
La editorial es Ed.Libraco.
Actualmente hay algunas existencias.
Mi libro de Historia tiene 254 páginas.Sin embargo puede ocurrir que el archivo Libro se encuentre en una carpeta diferente, que contenga (por ejemplo) todas las clases de nuestro proyecto. En ese caso debemos de añadir a nuestro código la siguiente instrucción:
import nombreCarpeta.Libro;
Las clases y la Herencia.
Partiendo de una clase, podemos crear otra clase con los mismos atributos y métodos, a los que podemos añadir otros nuevos que necesitemos para que se adapte mejor a nuestras necesidades. A esto se le llama “herencia”. Siguiendo con la clase que hemos creado en el apartado anterior Libro, vamos a crear la clase Enciclopedia.
public class Enciclopedia extends Libro{
public String tipolibro;
public int anyo;
public int numerotomos;
public Enciclopedia (String tema, int paginas, String editorial){
super(tema,paginas,editorial);
this.tipolibro="consulta";
}
public void caracteristicas(int anyo, int numerotomos){
this.anyo=anyo;
this.numerotomos=numerotomos;
}
}El primer detalle que vemos es que después del nombre de la nueva clase, debemos de añadir la palabra reservada «extends» seguido del nombre de la clase de la cual se hereda.
A continuación debemos de declarar los nuevos atributos que va a tener la nueva clase.
En el constructor de la clase, ponemos los parámetros que debamos de incluir para instanciar un objeto de la nueva clase. En este caso hemos decidido establecer como fijo el tipo de libro como «consulta». También se podía haber añadido como parámetro del constructor e incluirlo después como atributo.
Otra expresión obligada es la palabra reservada «super» seguido de los parámetros que tenía la clase de origen.
El resto queda como una clase más. Los métodos y atributos de la clase de origen quedan heredados por la que que hereda (aunque no aparezcan en su definición. Veamos como ejemplo la clase Enciclopedia que va a heredar de Libro.
public class Enciclopedia extends Libro{
public String tipolibro;
public int anyo;
public int numerotomos;
public Enciclopedia (String tema, int paginas, String editorial){
super(tema,paginas,editorial);
this.tipolibro="consulta";
}
public void caracteristicas(int anyo, int numerotomos){
this.anyo=anyo;
this.numerotomos=numerotomos;
}
}A continuación un código que llame a la clase Enciclopedia. La guardamos en el archivo que tendrá de nombre el de la nueva clase (Enciclopedia)
public class Prueba3 {
public static void main(String[] args) {
Enciclopedia mienciclopedia=new Enciclopedia("Informática",2500,"Canaya");
mienciclopedia.caracteristicas(2020,20);
mienciclopedia.ejemplares(8);
System.out.println("Tengo una enciclopedia de "+mienciclopedia.tema+".");
System.out.println("Tiene "+mienciclopedia.paginas+ " páginas.");
System.out.println("Es un libro de "+mienciclopedia.tipolibro+".");
System.out.println("Tiene "+mienciclopedia.numerotomos+" tomos.");
System.out.println("Es del año "+mienciclopedia.anyo+".");
System.out.println("En tienda, sus existencias son: "+mienciclopedia.existencias+".");
}
}Resultado:
Tengo una enciclopedia de Informática.
Tiene 2500 páginas.
Es un libro de consulta.
Tiene 20 tomos.
Es del año 2020.
En tienda, sus existencias son: pocas.Es probable que alguno de los atributos o métodos de la clase inicial, no se
adapten completamente a nuestra nueva clase. Este caso se soluciona reescribiendo el método o el atributo dentro de la nueva clase, para que así se adapte a lo que se necesita.
public class Enciclopedia extends Libro{
public String tipolibro;
public int anyo;
public int numerotomos;
public Enciclopedia (String tema, int paginas, String editorial){
super(tema,paginas,editorial);
this.tipolibro="consulta";
}
public void caracteristicas(int anyo, int numerotomos){
this.anyo=anyo;
this.numerotomos=numerotomos;
}
public void ejemplares(int cantidad){
this.cantidad=cantidad;
if (cantidad>15){
this.existencias="muchas";
}
else if (cantidad>5){
this.existencias="algunas";
}
else if (cantidad>0) {
this.existencias = "pocas";
}
else {
this.existencias="agotado";
}
}
}Hemos reescrito el método ejemplares modificando los valores para que se adapte al nuevo tipo de libro. Ahora al ejecutar el código anterior el resultado será:
Tengo una enciclopedia de Informática.
Tiene 2500 páginas.
Es un libro de consulta.
Tiene 20 tomos.
Es del año 2020.
En tienda, sus existencias son: algunas.También se podía haber definido la clase Enciclopedia, incluyendo en su definición el parámetro “utilidad”, (que sería asignado en este caso al atributo .tipolibro). Esto nos daría más flexibilidad en la creación de objetos Enciclopedia, ya que podríamos definir varios tipos de enciclopedia (consulta, ocio, idiomas…).
public class Enciclopedia extends Libro{
public String tipolibro;
public int anyo;
public int numerotomos;
public Enciclopedia (String tema, int paginas, String editorial, String utilidad){
super(tema,paginas,editorial);
this.tipolibro=utilidad;
}
public void caracteristicas(int anyo, int numerotomos){
this.anyo=anyo;
this.numerotomos=numerotomos;
}
public void ejemplares(int cantidad){
this.cantidad=cantidad;
if (cantidad>15){
this.existencias="muchas";
}
else if (cantidad>5){
this.existencias="algunas";
}
else if (cantidad>0) {
this.existencias = "pocas";
}
else {
this.existencias="agotado";
}
}Resultado:
Tengo una enciclopedia de Informática.
Tiene 2500 páginas.
Es un libro de estudio.
Tiene 20 tomos.
Es del año 2020.
En tienda, sus existencias son: algunas.Ejemplo con clases.
En este ejemplo se gestiona un complejo hotelero formado por varios edificios. Cada edificio tendrá varias plantas con varias puertas. Necesitaremos datos como la fecha de entrada y la fecha de salida para cada habitación ocupada. También tendremos habitaciones libres.
Tendremos un método para ocupar la habitación y otro para desocuparla. Otro método nos mostrará los datos principales de cada habitación.
import java.time.LocalDate;
public class Habitacion {
public int edificio;
public int planta;
public int puerta;
public String ocupacion;
public LocalDate fecha_entrada;
public LocalDate fecha_salida;
public Habitacion(int edificio,int planta,int puerta){
this.edificio=edificio;
this.planta=planta;
this.puerta=puerta;
this.ocupacion="LIBRE";
}
public String toString(){
String cadena=("La habitación del edificio "+edificio+" planta "
+planta+" puerta "+puerta+ " está "+ocupacion);
return cadena;
}
public void ocupar(LocalDate fecha_entrada, int dias_ocupacion){
this.fecha_entrada=fecha_entrada;
this.fecha_salida=fecha_entrada.plusDays(dias_ocupacion);
this.ocupacion="OCUPADA";
}
public void desocupar(){
this.ocupacion="LIBRE";
}
}En este código de ejemplo, configuramos todas las habitaciones inicialmente como libres. Todas las habitaciones, pasarán a formar parte de un ArrayList de objetos.
Ocuparemos tres habitaciones, y mostraremos los datos de todas las habitaciones ocupadas.
import java.time.LocalDate;
import java.util.ArrayList;
public class Prueba3 {
public static void main(String[] args) {
ArrayList<Habitacion> habitaciones = new ArrayList<>();
for (int puerta=0; puerta<5; puerta++){
for (int planta=0; planta<4; planta++){
for (int edificio=0; edificio<3; edificio++){
Habitacion nuevaHabitacion = new Habitacion(puerta,planta,edificio);
habitaciones.add(nuevaHabitacion);
}
}
}
LocalDate entrada =LocalDate.of(2024,12,26);
habitaciones.get(19).ocupar(entrada,10);
habitaciones.get(33).ocupar(entrada,30);
entrada=LocalDate.of(2024,12,31);
habitaciones.get(45).ocupar(entrada,6);
for (int k=0; k<habitaciones.size(); k=k+1){
if (habitaciones.get(k).ocupacion=="OCUPADA"){
System.out.println(habitaciones.get(k));
System.out.println("Fecha entrada: "+habitaciones.get(k).fecha_entrada);
System.out.println("Fecha salida: "+habitaciones.get(k).fecha_salida+"\n");
}
}
}
}Resultado:
La habitación del edificio 1 planta 2 puerta 1 está OCUPADA
Fecha entrada: 2024-12-26
Fecha salida: 2025-01-05
La habitación del edificio 2 planta 3 puerta 0 está OCUPADA
Fecha entrada: 2024-12-26
Fecha salida: 2025-01-25
La habitación del edificio 3 planta 3 puerta 0 está OCUPADA
Fecha entrada: 2024-12-31
Fecha salida: 2025-01-06