Saltar al contenido principal

Práctica 6 - POO en el entorno BlueJ. Diseño de clases sencillas

Un primer objetivo de esta práctica es familiarizarse con el entorno de programación en Java BlueJ, en lo que se refiere a su entorno gráfico de manipulación de clases y objetos orientado a comprender la POO. Otro objetivo es repasar los conceptos estudiados en actividades anteriores que son comunes entre el paradigma imperativo y el de POO. También nos familiarizaremos con el diseño de clases sencillas, sus componentes fundamentales (campos, métodos constructores y métodos), su implementación y la creación de nuevas clases utilizando otras para resolver problemas más complejos, haciendo hincapié en los distintos tipos de interrelación que pueden aparecer entre clases y cómo utilizar los elementos de unas clases en otras.

Para realizar la práctica descarga a tu equipo el contenido del archivo ProyectoPOO.zip que está disponible en el Anillo Digital Docente (asegúrate de descomprimir dicho archivo en tu equipo para poderlo utilizar).

Fase 1. Herramientas del entorno gráfico de BlueJ para POO

Ejercicio 1.1

Abre el proyecto denominado ProyectoPOO. Para ello puedes ir al menú Project | Open Project…, y buscarlo dentro de la carpeta que habeis descomprimido en vuestro equipo. Se abrirá una ventana que mostrará el diagrama UML de las clases contenidas en dicho proyecto: Punto2D, Triangulo y Teclado. Puede abrirse, también, haciendo doble clic en el icono denominado package.bluej existente en la carpeta descargada. Visualiza el aspecto de la ventana de proyecto que se ha abierto y fíjate en los detalles de los elementos que aparecen ya que su significado es importante.

flowchart LR
  TRI["Triangulo"] -.->|"utiliza"| PUNTO["Punto2D"]
  PUNTO -.->|"utiliza"| TECLADO["Teclado"]

  classDef clase fill:#e6f5f3,stroke:#0f766e,color:#16324f,stroke-width:1.5px;
  class TRI,PUNTO,TECLADO clase;

Es posible que los iconos de las clases Punto2D, Triangulo y Teclado estén sombreados, indicando que el código Java que les corresponde no ha sido compilado. Si es el caso, compílalas seleccionándolas y eligiendo la opción compile que aparecerá en el menú emergente al hacer clic con el botón derecho del ratón o con el botón compile del entorno en la ventana de proyecto. Observa el cambio de imagen del icono.

Haciendo doble clic sobre el icono de cada una de las clases, es posible acceder al código fuente en Java que corresponde a cada una de ellas. Lee atentamente las descripciones de cada una de las clases y echa un primer vistazo a su código Java intentando comprenderlo mediante su análisis. Te resultará de utilidad leer los comentarios de documentación que acompañan a dicho código fuente.

Dedícale el tiempo necesario hasta conseguir una comprensión suficiente del mismo si algunos elementos del código que aparece no te resultan conocidos. Esto es especialmente importante para el desarrollo posterior de la presente actividad.

Ejercicio 1.2

Con BlueJ, es posible crear objetos individuales de cualquier clase e interactuar con ellos invocando sus métodos no privados. El objetivo que se persigue con ello es poder desarrollar sin errores partes del código del programa sin la obligación de tener que completar dicho programa para comprobar que cada método es correcto y funciona. Selecciona la clase Punto2D y haz clic con el botón derecho del ratón. En el menú emergente, ahora que la clase está compilada, aparecen las operaciones habituales disponibles para las clases (abrir editor, compilar…). Además, pueden observarse en el menú contextual los constructores de la clase y los encabezados de los métodos de estáticos (static).

Selecciona el primer constructor para la clase Punto2D (new Punto2D()) para crear un nuevo objeto de esta clase. En el cuadro diálogo que aparece, además de mostrar los comentarios de documentación del constructor escritos en el código fuente, se te solicitará un nombre para el objeto que se va a crear (aparecerá por defecto el nombre punto2D1, lo puedes dejar tal cual, sin modificar).

Una vez que se ha creado el objeto, aparecerá en el banco de objetos con el nombre que se le haya dado (punto2D1 si no se ha modificado) un icono que lo representa (generalmente de color rojo). BlueJ ofrece la posibilidad, seleccionando un objeto del banco de objetos con el botón derecho, de inspeccionar dicho objeto, viendo el valor que tienen sus campos en un determinado momento y también permite ejecutar sus métodos no privados a través del menú contextual que aparece. Inspecciona el objeto punto2D1 con la opción adecuada y observa el cuadro de diálogo que aparece. ¿Cuáles son los valores de sus atributos? ¿Por qué?

Ventana de BlueJ con las clases, el banco de objetos y el bloque de código.

Clases, objetos y bloque de código en BlueJ
  • Para el atributo X el valor es 0.0 y para el atributo Y también es 0.0.
  • La razón es que el objeto se ha creado utilizando el constructor por defecto, el cual inicializa ambos atributos a 0.0.

Para el punto creado ejecuta de forma similar los métodos que devuelven los valores de las coordenadas y el cuadrante al que pertenece el punto. Observa lo que aparece en los cuadros de diálogo. Analiza el código correspondiente a los métodos si es necesario y responde a las preguntas: ¿Cómo se llaman? ¿Qué hacen? ¿Qué valores devuelven?

  • Para los valores de las coordenadas:
  • Los métodos son getX() y getY() que, respectivamente, obtienen la coordenada X y la coordenada Y del punto.
    • Los valores son los mismos que en el apartado anterior (X == 0.0, Y == 0.0).
  • Para los valores del cuadrante:
  • El método es cuadrante() que calcula el cuadrante al que pertenece el punto.
    • El valor es 0, lo que indica que el punto está en los ejes.

Utiliza los otros dos constructores para generar dos objetos de clase Punto2D. El primero para generar el punto de coordenadas (2.5,-1.5) y el segundo para generar un clon de este último recién creado. Observa los cuadros de diálogo que se han mostrado. ¿Qué información has tenido que introducir? Para poder comprobar que efectivamente los dos últimos puntos son iguales, ¿qué has tenido que hacer? ¿Hay otras posibilidades para hacerlo?

  • Para el primer punto se ha utilizado el constructor por parámetros, pasando como argumentos los valores 2.5 y -1.5 respectivamente.
  • Para el segundo punto se ha utilizado el constructor copia, pasando como argumento el nombre del objeto anterior, es decir, punto2D2.
  • Además de inspeccionar los atributos de cada objeto por separado, es posible utilizar o bien el método mismoPuntoQue(Punto2D) o bien el método muyProximoA(Punto2D).

Ejercicio 1.3

Localiza e invoca desde el banco de objetos los métodos que permiten modificar los valores de las coordenadas de un punto a valores nuevos y utilízalos para cambiar las coordenadas del tercer punto creado de forma que sus valores sean (-2.0, 3.5). Localiza el código de dichos métodos en el código fuente y explica brevemente qué es lo que hacen.

  • Los métodos son setX(double), que reasigna el atributo de la coordenada X utilizando el valor pasado como argumento; y setY(double), que hace lo mismo pero para el atributo de la coordenada Y.

Ejercicio 1.4

Localiza e invoca desde el banco de objetos el método que muestra por pantalla las coordenadas del punto. Observa el cuadro de diálogo que aparece. Localiza el código de dicho método en el código fuente y explica brevemente qué es lo que hace. Aplícalo a los tres objetos de clase Punto2D creados. ¿Cómo se llama el método? ¿Qué información has tenido que introducir en el cuadro de diálogo? ¿Cómo la has tenido que introducir? ¿Aparece en la ventana de Terminal dicha información? ¿Qué valores de coordenadas se han mostrado?

  • Habría dos posibilidades, toString() y escribePunto(String), aunque las preguntas del ejercicio hacen referencia más bien a este último.
  • Hay que introducir un String que sería el mensaje que precede a las coordenadas del punto.
  • Se introduciría un texto delimitado por comillas dobles ("). Por ejemplo: "Punto 1: "
  • Sí, los valores son:
    • Punto 1: (0.0, 0.0)
    • Punto 2: (2.5, -1.5)
    • Punto 3: (-2.0, 3.5)

Ejercicio 1.5

Localiza e invoca desde el banco de objetos el método que permite desplazar un punto de una posición del plano a otra en relación a la que tenía anteriormente. Utilízalo para mover el punto que estaba en el origen de coordenadas 2 unidades a la derecha y 3 unidades hacia abajo. Localiza el código de dicho método en el código fuente y explica brevemente qué es lo que hace. ¿Cómo se llama el método? ¿Qué información has tenido que introducir en el cuadro de diálogo? ¿Cuáles son las nuevas coordenadas del punto desplazado?

  • El método es desplazamientoRelativo(int, int).
  • Hay que introducir el desplazamiento relativo en el eje X y el desplazamiento relativo en el eje Y.
  • Las nuevas coordenadas serían: (2.0, -3.0).

Ejercicio 1.6

Crea un nuevo objeto de forma análoga a ocasiones anteriores, esta vez de la clase Triangulo, utilizando el constructor apropiado y da valores a sus campos a través del cuadro de diálogo que aparece. Para conseguirlo es posible que tengas que construir previamente (si no la has hecho ya) tres puntos que sirvan como vértices para el nuevo triángulo.

Una vez generado, utiliza el inspector de objetos y localiza los objetos de la clase Punto2D con los que has construido el objeto de la clase Triangulo (en el cuadro de diálogo que aparece tendrás que hacer clic varias veces en los iconos con flechas que representan el valor de los atributos del objeto que son, a su vez, otros objetos). Comprueba que los valores que se observan se corresponden con las coordenadas de los puntos utilizados como vértices.

Ejercicio 1.7

Ejecuta el método escribir(String mensaje) del objeto triángulo y escribe lo que aparece en la ventana. Localiza en el código fuente de la clase Triangulo el método que realiza esta tarea y, mediante su análisis, comprueba que lo mostrado en la ventana de Terminal es coherente con el código del método.

  • Utilizando como parámetro "Triángulo 1: ", el resultado mostrado es el siguiente: Triángulo 1: [V1(2.0, 3.0);V2(2.5,-1.5);V3(-2.0,3.5)]
  • El código del método lo único que hace es concatenar el mensaje con el resultado de llamar al método toString(), el cual genera la representación textual de los tres vértices que componen el triángulo.

Ejercicio 1.8

Ejecuta el método perimetro() del objeto triángulo, escribe el resultado obtenido y describe cómo lo comunica el entorno BlueJ.

  • El resultado es un double cuyo valor es: 15.940119614857917.
  • BlueJ lo comunica abriendo una ventana emergente que muestra la descripción del método y un recuadro con el tipo de dato de salida y su valor.

Ejercicio 1.9

Modifica el tercer punto creado para que se convierta en el origen de coordenadas. ¿Cómo lo has hecho? Descríbelo brevemente.

  • Desde el banco de objetos:
    1. Seleccionar el objeto punto2D3;
    2. Hacer click con el botón derecho, seleccionar el método setX(double) e introducir el valor 0.0 como argumento;
    3. Lo mismo que 2) pero seleccionando setY(double).

Ejercicio 1.10

Ejecuta de nuevo el método escribir(String mensaje) del objeto triángulo y escribe lo que aparece en la ventana. Compáralo con el resultado obtenido en el ejercicio 1.7. ¿Qué puede observarse? ¿Por qué? ¿Qué está ocurriendo?

  • Las coordenadas del punto 3 (0.0, 0.0) son distintas de las del vértice 3 del triángulo (-2.0, 3.5).
  • La razón es que son objetos diferentes.
  • Al crear el triángulo se utilizó el constructor por parámetros, el cual inicializa los atributos creando una copia de los objetos pasados como argumentos. Al crear una copia, los atributos contienen objetos independientes de aquellos que han sido pasados como argumento. Esto se debe a que Java utiliza el “paso por referencia” a la hora de indicar los parámetros de un método y si no se hubiera creado una copia, el punto 3 y el vértice 3 serían el mismo objeto (y por consiguiente tendrían los mismos valores).

Ejercicio 1.11

Como todo lo visto, tenemos que saber distinguir entre los métodos que BlueJ nos permite acceder desde los iconos de clase y los que nos permite acceder desde los iconos de los objetos. Esto es coherente con el hecho de cuando un método es estático (static) y cuando es de objeto (no estático). Localiza mediante el menú contextual (botón derecho) aplicado al icono de la clase Triangulo el método leerTriangulo() y ejecútalo. Observa cómo se produce la comunicación mediante la ventana de Terminal y cuando acaba su ejecución observa el cuadro de diálogo que aparece. Nos permitirá generar un nuevo objeto de la clase (aparecerá en el banco de objetos) si utilizamos en botón Obtener (get).

Fase 2. Edición y compilación con BlueJ

Ejercicio 2.1

Vas a modificar el código fuente Java del proyecto editando un método de la clase Triangulo para que realice una nueva tarea. Dicho método comprobará si los vértices que forman el triángulo son válidos o no. Para que sean válidos deberían ser puntos distintos y no estar alineados, aunque se puede pensar en una forma más sencilla, teniendo en cuenta las longitudes de los lados, si se cumple que ninguno de los lados sea mayor o igual en longitud que la suma de los otros dos que forman el triángulo.

El código que tenemos que desarrollar es, por tanto, el del método esTriangulo() de la clase Triangulo. El esqueleto del método ya se encuentra en el código fuente de la clase Triangulo y está preparado para ser editado y completado. Edita el método y compila la clase Triangulo hasta que, en la línea de estado en la parte inferior de la ventana de edición, BlueJ te informe de que la clase ha sido compilada y de que no hay errores sintácticos. Mientras haya errores sintácticos, el compilador de Java indicará en esa misma línea la causa del error y, en la mayor parte de las ocasiones, BlueJ dará información adicional si se hace clic en el enlace que aparece mostrando el número de errores en la esquina inferior derecha de la ventana de edición.

Una vez que hayas compilado sin errores, crea nuevos objetos de la clase Punto2D y Triangulo (recuerda que cada compilación que se realiza elimina los objetos existentes ya que sólo existen en tiempo de ejecución) y comprueba que esTriangulo() se ejecuta de acuerdo con la nueva especificación. Cuando sea así, escribe a continuación las líneas de programa que hayas desarrollado en el código fuente del método escrito:

  • Ver código fuente.
public boolean esTriangulo () {
    // ***** EJERCICIO 2.1 *****

    // Comprobar si los vértices son distintos
    boolean verts_equal =
        vert1.mismoPuntoQue(vert2) ||
        vert1.mismoPuntoQue(vert3) ||
        vert2.mismoPuntoQue(vert3);

    // Calcular longitudes de los lados
    double side_a = vert1.distanciaA(vert2);
    double side_b = vert1.distanciaA(vert3);
    double side_c = vert2.distanciaA(vert3);

    // Comprobar si están alineados (violación de la desigualdad triangular)
    boolean verts_aligned =
        side_a >= side_b + side_c ||
        side_b >= side_a + side_c ||
        side_c >= side_a + side_b;

    // Triángulo válido si no hay vértices iguales ni alineados
    boolean esTrianguloValido = !verts_equal && !verts_aligned;

    // El triángulo es válido si los vértices no son iguales ni
    // están alineados
    boolean valid_triangle = !verts_equal && !verts_aligned;

    // 2. Devolver el resultado
    return valid_triangle;
}

Nota muy importante: en todo momento deben utilizarse criterios de diseño de POO y, por lo tanto, desarrollar las soluciones que más nos acerquen a ello. Para procurarlo, en todos los ejercicios de este apartado, se respetarán los encabezados de los métodos solicitados y se diseñarán con el concepto de objeto propietario this (por lo tanto, no serán static).

Ejercicio 2.2

Vas a modificar de nuevo el código fuente Java del proyecto editando otro método de la clase Triangulo para que realice otra nueva tarea. Dicho método calculará el área del triángulo. Localiza en el código fuente de la clase Triangulo el esqueleto incompleto del método que tienes que diseñar. Para poderlo hacer ten en cuenta que el problema puede resolverse aplicando la fórmula de Herón que permite calcular el área del triángulo conociendo las longitudes de sus lados. La fórmula de Herón es la siguiente:

\[ A = \sqrt{s(s-a)(s-b)(s-c)} \]

donde a, b y c son los valores de las longitudes de sus lados y s es el semiperímetro del triángulo.

Repite el mismo proceso de edición que en el ejercicio anterior y una vez que hayas compilado sin errores, crea nuevos objetos de la clase Punto2D y Triangulo y comprueba que el método area() se ejecuta adecuadamente y realiza el cálculo de forma correcta. Cuando sea así, escribe a continuación las líneas de programa que hayas desarrollado en el código fuente del método escrito:

  • Ver código fuente.
public double area () {
    // ***** EJERCICIO 2.2 *****

    // 0. Declaración de variables
    // SALIDA
    double area = 0.0;          // Área del triángulo
    // AUXILIARES
    double side_a = 0.0;        // Lado entre los vértices 1 y 2
    double side_b = 0.0;        // Lado entre los vértices 1 y 3
    double side_c = 0.0;        // Lado entre los vértices 2 y 3
    double semiperimeter = 0.0; // Semiperímetro del triángulo

    // 1. Calcular el área del triángulo
    // Calcular los lados del triángulo y el semiperímetro
    side_a = this.vert1.distanciaA(this.vert2);
    side_b = this.vert1.distanciaA(this.vert3);
    side_c = this.vert2.distanciaA(this.vert3);
    semiperimeter = this.perimetro() * 0.5;
    // Calcular el área según la fórmula de Herón
    area = Math.sqrt(
        semiperimeter * (semiperimeter - side_a)
        * (semiperimeter - side_b) * (semiperimeter - side_c)
    );

    // 2. Devolver el resultado
    return area;
}

Ejercicio 2.3

De manera análoga a los apartados anteriores, desarrolla los métodos baricentro() y esRectangulo() atendiendo a las especificaciones escritas en los comentarios y cuyo esqueleto está contenido de manera incompleta en el código fuente de la clase Triangulo. Una vez concluidos, compruébalos introduciendo los valores que sean necesarios. Describe, a continuación, cómo has hecho dicha comprobación.

  • Ver código fuente. Para comprobarlo, crear tres puntos: P1(0.0, 0.0); P2(1.0, 0.0); P3(0.0, 1.0). El resultado es true en ambos métodos.
public Punto2D baricentro () {
    // ***** EJERCICIO 2.3 *****

    // 0. Declaración de variables
    // SALIDA
    Punto2D barycenter; // Punto con las coordenadas del baricentro
    // AUXILIARES
    double coord_x = 0.0; // Coordenada X del punto que hace de baricentro
    double coord_y = 0.0; // Coordenada Y del punto que hace de baricentro

    // 1. Calcular el punto que hace de baricentro
    // Calcular las coordenadas asociadas sabiendo que el baricentro está ubicado
    // siempre a 1/3 de la distancia del vértice opuesto
    coord_x = (this.vert1.getX() + this.vert2.getX() + this.vert3.getX()) / 3;
    coord_y = (this.vert1.getY() + this.vert2.getY() + this.vert3.getY()) / 3;
    // Instanciar el punto que hace de baricentro
    barycenter = new Punto2D(coord_x, coord_y);

    // 2. Devolver el resultado
    return barycenter;
}
public boolean esRectangulo () {
    // ***** EJERCICIO 2.3 *****

    // 0. Declaración de variables
    // SALIDA
    boolean right_triangle = false; // ¿Es triángulo rectángulo?
    // AUXILIARES
    double side_a = 0.0; // Lado entre los vértices 1 y 2
    double side_b = 0.0; // Lado entre los vértices 1 y 3
    double side_c = 0.0; // Lado entre los vértices 2 y 3
    double hypotenuse = 0.0; // Hipotenusa
    double cathetus_1 = 0.0; // Cateto 1
    double cathetus_2 = 0.0; // Cateto 2

    // 1. Determinar si es un triángulo rectángulo
    // Calcular la longitud de cada lado como la distancia entre
    // los vértices correspondientes
    side_a = this.vert1.distanciaA(this.vert2);
    side_b = this.vert1.distanciaA(this.vert3);
    side_c = this.vert2.distanciaA(this.vert3);
    // Determinar qué lado es la hipotenusa y cuáles los catetos
    if (side_a > side_b && side_a > side_c)
    {
        hypotenuse = side_a;
        cathetus_1 = side_b;
        cathetus_2 = side_c;
    }
    else if (side_b > side_a && side_b > side_c)
    {
        hypotenuse = side_b;
        cathetus_1 = side_a;
        cathetus_2 = side_c;
    }
    else
    {
        hypotenuse = side_c;
        cathetus_1 = side_a;
        cathetus_2 = side_b;
    }
    // Para comprobar si es rectángulo hay que aplicar el teorema
    // de Pitágoras: a^2 + b^2 = c^2
    // IMPORTANTE: en Java no se pueden comparar doubles directamente
    // debido a que utilizan muchos decimales de precisión. Por ello,
    // es mejor truncar los valores y quedarse con pocos decimales
    // (por ejemplo 2)
    right_triangle =
        Math.floor((cathetus_1*cathetus_1 + cathetus_2*cathetus_2) * 100) / 100
        <=
        Math.floor((hypotenuse*hypotenuse) * 100) / 100;

    // 2. Devolver el resultado
    return right_triangle;
}

Fase 3. Creación de clases

Utilizando como base las clases Punto2D y Triangulo desarrolladas en apartados anteriores, vamos a implementar, de forma completa desde cero, la clase Circunferencia, para representar circunferencias caracterizadas por su centro y radio.

Como se ha mencionado con anterioridad, ha de imperar el espíritu de diseño con orientación a objetos en las soluciones que se desarrollen en los ejercicios propuestos. Habrá que huir, pues, de soluciones que pasen por métodos de clase (static) si existe una solución clara e intuitiva que utilice el concepto de objeto propietario this. Se pueden añadir comentarios de documentación y de explicación para facilitar la comprensión de los códigos escritos.

Ejercicio 3.1

Genera una nueva clase denominada Circunferencia. En la plantilla de código que aparece de forma automática elimina todo el contenido para poder desarrollar los elementos que se adecuen a lo que perseguimos. Una vez vaciada, añade los campos necesarios para representar una circunferencia. Siguiendo el principio de ocultación, defínelos para que sean privados. ¿Qué campos has puesto?

private Punto2D center; // Centro de la circunferencia
private double radius; // Radio de la circunferencia

Ejercicio 3.2

Vamos a añadir ahora los métodos constructores de la clase. Primero escribiremos un constructor con dos parámetros que transmitirán valor a los atributos del objeto creado. Una vez completado y comprobado, escribiremos un método constructor copia que sirva para clonar objetos de clase circunferencia. El código fuente de la clase Triangulo te puede servir de orientación. ¿Qué cabeceras has puesto a los métodos constructores?

// Constructor por parámetros:
public Circunferencia(Punto2D center, double radius) { /* ... */ }
// Constructor copia:
public Circunferencia(Circunferencia circumference) { /* ... */}

Ejercicio 3.3

El siguiente paso podría ser escribir métodos observadores y modificadores. Hay que recordar que cuando tenemos atributos private los métodos get y set pueden ser necesarios.

Elige un campo y escribe dichos métodos para este campo. ¿Qué cabeceras has puesto a los métodos?

// Métodos observadores
public Punto2D getCenter() { /* ... */ }
public double getRadius() { /* ... */ }
// Métodos modificadores
public void setCenter(Punto2D center) { /* ... */ }
public void setRadius(double radius) { /* ... */ }

Ejercicio 3.4

Basándonos en el método leerTriangulo() de la clase Triangulo, vamos a escribir el método leerCircunferencia() y lo vamos a añadir a la clase que estamos desarrollando. ¿Qué cabeceras has puesto al método?

public static Circunferencia leerCircunferencia() { /* ... */ }

Ejercicio 3.5

De la misma forma que en el ejercicio anterior, basándonos en el método toString() de la clase Triangulo, vamos a escribir el método toString() aplicado a circunferencias y lo vamos a añadir a la clase que estamos desarrollando. ¿Qué cabeceras has puesto al método?

@Override
public String toString() { /* ... */ }

Ejercicio 3.6

Desarrolla el método escribir() en la clase Circunferencia, de forma similar al método del mismo nombre desarrollado en la clase Triangulo. ¿Qué cabeceras has puesto al método?

public void escribir(String msg) { /* ... */ }

Ejercicio 3.7

Desarrolla el método area() en la clase Circunferencia, que calcule el área que encierra la circunferencia objeto dueño. ¿Qué cabeceras has puesto al método?

public double area() { /* ... */ }

Ejercicio 3.8

Desarrolla el método perimetro() en la clase Circunferencia, que calcule el perímetro de la circunferencia objeto dueño. ¿Qué cabeceras has puesto al método?

public double perimetro() { /* ... */ }

Ejercicio 3.9

Desarrolla los métodos necesarios para calcular la posición relativa (interior, exterior o perteneciente a) de un punto respecto de una circunferencia. Observa que habrá diferentes formas de afrontar el problema y darle solución. Describe brevemente la estrategia que has seguido y los métodos que has desarrollado.

  • Para comprobar la posición relativa del punto, una posible estrategia puede ser:
    1. Calcular la distancia del punto pasado como argumento al centro de la circunferencia.
    2. La posición relativa depende del signo de la distancia:
      • Si la distancia es negativa (<0), la posición es “interior”.
      • Si no, si la distancia es igual a 0 (==0), la posición es “perteneciente a”.
      • Si no, la distancia es positiva (>0) y la posición es “exterior”.

Fase 4. Método main

En esta fase vamos a completar nuestro proyecto con una clase Figuras que contiene un método (main) que lanzará la ejecución de nuestro programa. El programa pide al usuario que elija entre un triángulo y una circunferencia y, una vez hecho, lee valores para construirlo y, después de mostrar su información por pantalla, calcula su área y su perímetro y los muestra por pantalla. El objetivo que perseguimos en este apartado de la actividad es conseguir que funcione correctamente dicho programa.

MUY IMPORTANTE: Es necesario tener en cuenta que gracias a la interfaz de BlueJ todo lo que se ha realizado hasta ahora ha sido sin la necesidad de desarrollar un programa con un objetivo concreto. No se ha tenido que escribir un método main para lanzar el comienzo de la ejecución de ninguno de los métodos de las clases implementadas. Esta forma de trabajar será la que sigamos de forma habitual en nuestra tarea de programar, desarrollando y probando el funcionamiento de aquellas partes que sean necesarias, en la medida de lo posible, de forma independiente del resto, consiguiendo así hacer de nuestro trabajo una tarea más sencilla.

flowchart TB
  direction TB
  FIG["Figura (abstracta)"] -->|"se especializa en"| TRI["Triangulo"]
  FIG -->|"se especializa en"| CIR["Circunferencia"]

  classDef madre fill:#e6f5f3,stroke:#0f766e,color:#16324f,stroke-width:1.5px;
  classDef hija fill:#fde8e2,stroke:#e76f51,color:#7c2d1d,stroke-width:1.5px;
  class FIG madre;
  class TRI,CIR hija;

EPILOGO: Al desarrollar el método main habrás observado que el código desarrollado es muy similar tanto si el usuario elige un triángulo como si elige una circunferencia. La Programación Orientada a Objetos incorpora los mecanismos de herencia, clases abstractas y polimorfismo para solucionar las duplicidades de código en este tipo de situaciones. Para este caso, se declararía una clase abstracta Figura con los campos y métodos comunes a Triangulo y Circunferencia. Después se usaría el mecanismo de herencia para que ambas clases heredasen de la clase madre Figura los elementos comunes a ambos tipos de objetos. Habría que eliminar dichos elementos en las clases hijas. Por último, en el método main de la clase Figuras se declararía un objeto de la clase Figura al que se le asignaría una referencia a la clase correspondiente (Triangulo o Circunferencia) en función del tipo de figura elegido por el usuario. El código duplicado se escribiría ahora una única vez y el mecanismo de polimorfismo se encargaría de invocar a los métodos correctos de las clases hijas en función de la clase a la que esté apuntando la referencia.

Como podéis ver, el mecanismo de herencia es complejo de comprender y de utilizar, pero permite resolver de una manera muy eficiente algunos problemas donde los objetos que intervienen tienen características comunes.