Codificación de diagramas de clases

Para la codificación se parte del diagrama de clases detallado —el cual contiene la lógica del problema que queremos resolver— y el diagrama de secuencia para la función main() de la clase Principal —el cual contiene la presentación hacia el usuario.

Clases de la lógica del problema:

Seguiremos el siguiente algoritmo y posteriormente explicaremos cada parte:

A partir de la clase utilice el identificador de la clase y escríbalo utilizando la siguiente estructura:

Codificación de diagramas de clases

La palabra reservada public sirve para indicar que la clase será visible a los programadores y class indica que empezaremos la declaración de una clase. Después seguirá el identificador de la clase, es importante recordar que va sin acentos, sin espacios, capitalizada e iniciando con mayúscula.

Las dos diagonales, sirven para poner comentarios (igual que en el pseudocódigo, en este caso el comentario queda hasta el final de la línea. Aquí se sugiere poner una línea de guiones para delimitar el área que dedicaremos a atributos y métodos. Observa las áreas sombreadas. El área azul se conoce como el ámbito de la clase. Todo lo que esté incluido en esta zona es su sección privada, a menos que se indique otra visibilidad.

Se recomienda declarar todos los atributos en la parte inicial y todos los métodos en la parte de abajo: en el orden: constructor, lógica de la clase, getters y setters.

Codifique los atributos, recuerde que todos son privados, por lo que para cada uno de ellos deberá especificar:


{
private tipo nombreDelIdentificadorDelAtributo;  // descripción
}

La palabra reservada private se utiliza por el principio de encapsulamiento, aunque el lenguaje de programación permite poner público (public) o protegido (protected) o no especificarlo, SIEMPRE deben especificarse en private los atributos.

Para cada método sustituye la visibilidad por el identificador adecuado: + como public , – como private y # como protected. Esta última se utiliza en raras ocasiones, así que por lo pronto centrémonos en public y private. Después, coloca el tipo de dato; recuerda, usa int para enteros, double para números con punto decimal, en caso de requerir otras precisiones puedes usar los tipos que proporciona Java; utiliza la clase String para almacenar datos alfanuméricos como nombres de personas, párrafos de texto, etc.


{
private|protected tipo identificadorMétodo(parametros) {
   // utilice esta área para escribir el código del método,
   // el cual se genera a partir de un diagrama de flujo

   return valorDelTipo;  // sólo si el tipo no es void
}
}

La palabra this se refiere al objeto o instancia que se modifica.

En los constructores, hay que darle valores iniciales a los atributos que garantice que están bien colocados los atributos. Para el caso particular de los getters se puede avanzar escribiendo la instrucción de retorno de valor:


{
private|protected tipo getAtributo() {
   // cálculos previos para regresar un atributo

   return this.atributo;
}
}

En el caso particular de los setters se puede avanzar escribiendo la instrucción de retorno de valor, que se envía como parámetro. En algunos casos se requerirá validar las excepciones previamente y actualizar el valor de los atributos dependientes del que se está modificando.


{
private|protected tipo getAtributo() {
   // Manejo de excepciones en la asignacion del atributo

   return this.atributo;
}
}

En este punto sólo se ha construido el “esqueleto” de la clase.

Ejemplo:

A partir del siguiente diagrama de detallado de la clase Triángulo, se realiza la codificación inicial de la clase:

Codificación de diagramas de clases
clase

Codificación del esqueleto de la clase:

Nota: Los nombres o identificadores en Java no pueden llevar acentos, por eso se quitó a partir del diagrama de clases hacia la codificación.
atributos

Codificación de la sección de atributos:


{
public class Triangulo {
    // ------------------------------------------------------------
    // Atributos:

    private double base;
    private double altura;
    private double area;

    // ------------------------------------------------------------
    // Métodos:

}
}

Codificación de la sección de atributos:

atributos

{
public class Triangulo {
    // ------------------------------------------------------------
    // Atributos:

    private double base;
    private double altura;
    private double area;

    // ------------------------------------------------------------
    // Métodos:

    // constructor(es):
    public Triangulo() {
        this.base = 1;
        this.altura = 1;
        this.calcularArea(); // llamada al procedimiento que calcula el área
    }

    // continuamos …

}
}

Codificación de la sección de atributos:

getters

{
public class Triangulo {
    // ------------------------------------------------------------
    // Atributos:

    private double base;
    private double altura;
    private double area;

    // ------------------------------------------------------------
    // Métodos:

    // constructor(es):
    public Triangulo() {
        this.base = 1;
        this.altura = 1;
        this.calcularArea(); // llamada al procedimiento que calcula el área
    }

    // lógica de la clase:
    private void calcularArea() {
        // instrucciones para obtener el área del triángulo
        this.area = (this.altura * this.area) / 2;
    }

    // continuamos …

}
}

Codificación de la sección de atributos:

lógica de la clase

{
public class Triangulo {
    // ------------------------------------------------------------
    // Atributos:

    private double base;
    private double altura;
    private double area;

    // ------------------------------------------------------------
    // Métodos:

    // constructor(es):
    public Triangulo() {
        this.base = 1;
        this.altura = 1;
        this.calcularArea(); // llamada al procedimiento que calcula el área
    }

    // lógica de la clase:
    private void calcularArea() {
        // instrucciones para obtener el área del triángulo
        this.area = (this.altura * this.area) / 2;
    }

    // getters:
    public double getBase() {
        return this.base;
    }

    public double getAltura() {
        return this.altura;
    }

    public double getArea(){
        return this.area;
    }

  // continuamos …

}
}

Codificación de la sección de atributos:

setters

{
public class Triangulo {
    // ------------------------------------------------------------
    // Atributos:

    private double base;
    private double altura;
    private double area;

    // ------------------------------------------------------------
    // Métodos:

    // constructor(es):
    public Triangulo() {
        this.base = 1;
        this.altura = 1;
        this.calcularArea(); // llamada al procedimiento que calcula el área
    }

    // lógica de la clase:
    private void calcularArea() {
        // instrucciones para obtener el área del triángulo
        this.area = (this.altura * this.area) / 2;
    }

    // getters:
    public double getBase() {
        return this.base;
    }

    public double getAltura() {
        return this.altura;
    }

    public double getArea(){
        return this.area;
    }

    // setters:
    public void setBase(double value) {
        // verificaciones previas a la asignación… excepciones!!!
        this.base = value;
    }

  // setters:
    public void setAltura(double value) {
        // verificaciones previas a la asignación… excepciones!!!
        this.altura = value;
    }

}
}

Codificación de la estructura de la clase Persona

Escribir

Basado en el diagrama de clases que se muestra a continuación, codifica el esqueleto de la clase Persona para calcular el índice de masa corporal de una persona, conociendo su peso y su estatura. Recuerda que el IMC se calcula como $imc\leftarrow \tfrac{peso} { estatura^2 }$

Codificación de la estructura de la clase Persona
estatura
private
double
calcularIMC()
imc
getEstatura()
this.peso
this.calcularIMC();
Debes escribir tu respuesta para recibir retroalimentación.

Método main() de la clase Principal

La codificación del método main() se hará a partir del diagrama de secuencia. En este apartado se codificarán los programas desarrollados con el prototipo de consola. La codificación de formularios se hará en otro material una vez abordados conceptos como herencia y polimorfismo con más detalle; así como arreglos y colecciones polimórficas de objetos.

Observa el siguiente video de la clase Triángulo que muestra cómo se ejecuta un programa en modo consola.

El siguiente diagrama de secuencia nos permite conocer cómo trabaja el programa o clase Principal, comunicándose con el usuario y coordinando las acciones con la lógica del programa que se ubica en la clase Triángulo.

Diagrama de secuencia l

El programa principal solicita al usuario la base y se queda esperando a que el usuario presente [Intro]; sucede lo mismo con la altura. El programa principal lo guarda en dos variables: base y altura, que deben ser de tipo double, porque se enviarán al triángulo y esos son los tipos de datos utilizados. Recordemos el diagrama de clase detallado de la clase funcional Triángulo que acabamos de revisar:

Diagrama de secuencia 2

Aunque no está completamente terminada esta clase ya es funcional. Para codificar el método main() de la clase Principal, seguiremos los siguientes pasos.


{
public class Principal {

}
}

{
public class Principal {

    public static void main( String[] args ) {
        
    }

}
}

¿Qué significa esta sentencia?

  • public: la visibilidad de la clase es pública y accesible desde el exterior.
  • static: es un método de clase, no es de instancia, por lo tanto no es necesario tener un objeto de la clase Principal para poder invocarlo.
  • void: no regresa ningún valor.
  • main: es el nombre del método que busca Java para ejecutar el programa, debe cumplirse toda la firma (o declaración) del método para que funcione.
  • String[]: en el tipo de dato del parámetro args indica que recibe una colección ordenada (arreglo) de argumentos de tipo alfanumérico desde la línea de comandos, (por ejemplo cuando escribes en la terminal dir *.docx para mostrar qué archivos hay en el directorio actual con extensión «docx», el argumento es “*.doc”, ahí hay un argumento para el programa dir; si escribes el comando time te permite cambiar la hora, la cual no necesita argumentos, pero time /T sólo muestra la hora, ahí hay un argumento “/T”). En este momento no se ocuparán, pero así debe estar declarado el método.
  • {} Las llaves de apertura y cierre: son el inicio y fin del procedimiento y equivalen a los símbolos inicio y fin del diagrama de flujo.

Al menos una instancia del diagrama de secuencia y las variables que solicita el programa principal al usuario, declara las variables a utilizar. El programa necesita recuperar del usuario, base y altura, y necesita crear una instancia de Triangulo con el operador new y el constructor de la clase.


{
public class Principal {

    public static void main( String[] args ) {
        // Declaración de variables:
        double    base;
        double    altura;
        Triangulo miTriangulo;

        // Inicializar le objeto con el constructor
       miTriangulo = new Triangulo();
   
    }
}
}

Pon mucha atención en el punto y coma que aparece al final como terminador de las instrucciones, líneas o sentencias que aparecen en la sección sombreada. Constituyen el cuerpo del método y terminan con un punto y coma “;”.

Las variables no son atributos, se encuentran declaradas dentro del ámbito del método main(), por lo que simplemente serán variables que se utilizarán en el método y se destruirán al salir. Se declaran con el tipo de dato seguido del identificador a utilizar. Recuerda que las clases pueden ser usadas como tipo de dato.

Los objetos, instancias de las clases, como miTriangulo, necesitan crearse después de declararse, para ello se utiliza el constructor.

Los tipos de datos primitivos (double, en este caso) no necesitan crearse con algún constructor.

Para la lectura se declara una instancia de la clase Scanner, observa cómo se pone y más adelante lo veremos con más detenimiento:


{
import java.util.Scanner;

public class Principal {

    public static void main( String[] args ) {
        // Declaración de variables:
        double    base;
        double    altura;
        Triangulo miTriangulo;
        Scanner   consola;

        // Inicializar le objeto con el constructor
        miTriangulo = new Triangulo();
        consola = new Scanner( System.in );
    }
}
}

Se utilizan los métodos de la instancia consola de la clase Scanner y next() lee la siguiente cadena String. Por su parte, nextInt() lee el siguiente entero y nextDouble() lee el siguiente número de punto flotante:


{
import java.util.Scanner;

public class Principal {

    public static void main( String[] args ) {
        // Declaración de variables:
        double    base;
        double    altura;
        Triangulo miTriangulo;
        Scanner   consola;

        // Inicializar le objeto con el constructor
        miTriangulo = new Triangulo();
        consola = new Scanner( System.in );

        // Lectura de variables:
        System.out.print ( "Valor de la base: " );
        base = consola.nextDouble();
        System.out.print ( "Valor de la altura: " );
        altura= consola.nextDouble();
    }
}
}

Las instrucciones de lectura en modo consola se componen de dos sentencias, la primera es la escritura de un texto: System.out.print(“Constante alfanumérica”); y después la lectura desde el objeto consola de la clase Consola:

Observa los tres momentos en los que Principal se comunica con triángulo, que corresponden a las líneas sombreadas:


{
import java.util.Scanner;

public class Principal {

    public static void main( String[] args ) {
        // Declaración de variables:
        double    base;
        double    altura;
        Triangulo miTriangulo;
        Scanner   consola;

        // Inicializar le objeto con el constructor
        miTriangulo = new Triangulo();
        consola = new Scanner( System.in );

        // Lectura de variables:
        System.out.print ( "Valor de la base: " );
        base = consola.nextDouble();
        miTriangulo.setBase( base );  // actualiza área automáticamente

        System.out.print ( "Valor de la altura: " );
        altura= consola.nextDouble();
        miTriangulo.setAltura( altura ); // actualiza área automáticamente

        // Escritura del resultado
        double area = miTrangulo.getArea(); // declara una variable temp.
    }
}
}

Como puedes observar, las variables se pueden declarar en cualquier parte del código. Se recomienda hacerlo en la parte superior pero cuando las usas e inmediatamente las desechas, puede omitirse esta sugerencia.

Recuerda colocar un texto indicando qué información se le otorga al usuario. En este caso, el operador “+” es de concatenación y lo que aparezca adelante, una variable double (en este ejemplo), se convertirá a texto (String) y se concatenará con texto anterior:


{
import java.util.Scanner;

public class Principal {

    public static void main( String[] args ) {
        // Declaración de variables:
        double    base;
        double    altura;
        Triangulo miTriangulo;
        Scanner   consola;

        // Inicializar le objeto con el constructor
        miTriangulo = new Triangulo();
        consola = new Scanner( System.in );

        // Lectura de variables:
        System.out.print ( "Valor de la base: " );
        base = consola.nextDouble();
        miTriangulo.setBase( base );  // actualiza área automáticamente

        System.out.print ( "Valor de la altura: " );
        altura= consola.nextDouble();
        miTriangulo.setAltura( altura ); // actualiza área automáticamente

        // Escritura del resultado
        double area = miTrangulo.getArea(); // declara una variable temp.
        System.out.println( "El valor del área es " + area );

    }
}
}

En verde está la solicitud de información de main() hacia el usuario, en azul está la creación del Triángulo y la asignación de los valores de los atributos con los setters, el morado recupera los datos de la salida (getArea()) y los muestra en la pantalla.


{
import java.util.Scanner;

public class Principal {

    public static void main( String[] args ) {
        // Declaración de variables, la inicialización puede ir aquí:
        Triangulo miTriangulo = new Triangulo();
        Scanner   consola     = new Scanner( System.in );

        // Lectura de variables:
        System.out.print ( "Valor de la base: " );
        miTriangulo.setBase( ( consola.nextDouble() );
           // actualiza área automáticamente

        System.out.print ( "Valor de la altura: " );
        miTriangulo.setAltura( consola.nextDouble() );
           // actualiza área automáticamente

        // Escritura del resultado
        System.out.println( "El valor del área es "+miTrangulo.getArea());

    }
}
}