Problemas con toString () y métodos de anulación

2020-02-27 java overriding tostring

Tengo un problema con este código. No está calculando el área correctamente. Lo necesito para calcular el área de la sección transversal de un cilindro / pistón y el área de superficie del cilindro. Si observa el resultado, parece que ambos valores son los mismos valores para cuando uso el método getArea (). ¿Java está confundido con getter sobre qué getArea () usar? texto fuerte Estoy tratando de anular getArea () [Área de superficie] con getArea () [área de sección transversal] pero no funciona.

import java.util.Scanner;

class Main {
  public static void main(String[] args) {
    Scanner scan = new Scanner(System.in);
    System.out.println(
        "\n\nInput the radius, then the height, then if the cylinder is filled (input 1 if it is filled and input 0 if not, and then enter the color");

    double radius = scan.nextDouble();
    double height = scan.nextDouble();
    int filled = scan.nextInt();

    boolean isFilled;
    if (filled == 1) {
      isFilled = true;
    } else {
      isFilled = false;
    }

    String c = scan.nextLine();
    String x = scan.nextLine();

    Cylinder cyl = new Cylinder(radius, height, isFilled, x);
    System.out.println("\n\n This is a Cylinder and its properties");
    System.out.println(cyl);

    Piston small= new Piston();
    System.out.println ("\n\n This is small Piston");
    System.out.println(small);

    Piston big = new Piston(55.6, 1234.4, true, "red", 1200, 12.3);
    System.out.println ("\n\n This is big Piston");
    System.out.println(big);
  }
}

class Shape {
  private String color = "yellow";
  private boolean filled;

  public Shape() {

  }

  public Shape(String color, boolean filled) {

    this.color = color;
    this.filled = filled;
  }

  public String getColor() {
    return color;
  }

  public void setColor(String color) {
    this.color = color;
  }

  public boolean isFilled() {
    return filled;
  }

  public void setFilled(boolean filled) {
    this.filled = filled;
  }

  public String toString() {
    return "\nThe color is : " + color + " and shape fill is : " + filled;

  }

}

class Cylinder extends Shape {
  private double cylinderRadius;
  private double cylinderHieght;

  public Cylinder() {
    cylinderHieght = 10;
    cylinderRadius = 2.5;
  }

  public Cylinder(double height, double radius) {
    cylinderRadius = radius;
    cylinderHieght = height;
  }

  public Cylinder(double height, double radius, boolean filled, String color) {
    super(color, filled);
    cylinderRadius = radius;
    cylinderHieght = height;
  }

  public double getRadius() {
    return cylinderRadius;
  }

  public double getHieght() {
    return cylinderHieght;
  }

  public double getArea() {
    double p = 3.14;
    return 2 * p * cylinderRadius * cylinderRadius + 2 * p * cylinderRadius * cylinderHieght;
  }

  public double getVolume() {
    double p = 3.14;
    return p * cylinderRadius * cylinderRadius * cylinderHieght;
  }

  @Override
  public String toString() {
    return super.toString() + " \nRadius= " + cylinderRadius + " Height= " + cylinderHieght
        + " Cylinder total surface Area= " + getArea() + " volume= " + this.getVolume() + ".";
  }
}

class Piston extends Cylinder{
  private double shaftLength;
  private double myPressure;

  public Piston(){
    shaftLength=1;
    myPressure=1;
  }
  public Piston(double height, double radius, boolean filled, String color, double length, double pressure){
    super(height, radius, filled, color);
    shaftLength=length;
    myPressure=pressure;
  }
  public double getShaftLength(){
    return shaftLength;
  }
  public double getPressure(){
    return myPressure;
  }
  @Override
  public double getArea(){
    return getRadius()*getRadius()*3.14;
  }
  public double getVolume(){
    return super.getVolume();
  }
 @Override
  public String toString(){
    return super.toString()+"\n the cross sectional area of Piston = "+this.getArea()+" shaftlength="+shaftLength+" pressure="+myPressure+" .";
  }
}

Aquí está la salida si pongo en un radio de 5 y una altura de 10.

Ingrese el radio, luego la altura, luego si el cilindro está lleno (ingrese 1 si está lleno e ingrese 0 si no, y luego ingrese el color 5 10 1 azul

Este es un cilindro y sus propiedades.

El color es: azul y el relleno de la forma es: verdadero Radio = 10.0 Altura = 5.0 Área de superficie total del cilindro = 942.0 volumen = 1570.0.

Este es pequeño pistón

El color es: amarillo y el relleno de la forma es: falso Radio = 2.5 Altura = 10.0 Superficie total del cilindro Área = 19.625 volumen = 196.25. El área de la sección transversal del pistón = 19.625 longitud del chaflán = 1.0 presión = 1.0.

Este es un gran pistón

El color es: rojo y el relleno de la forma es: verdadero Radio = 1234.4 Altura = 55.6 Superficie total del cilindro Área = 4784554.150400002 volumen = 2.6602121076224005E8. El área de la sección transversal del pistón = 4784554.150400002 Shaftlength = 1200.0 presión = 12.3.

Answers

Para aclarar, parece que esta es la situación:

  1. Tiene una clase ( Cylider ) que define un método ( getArea() ) para hacer una cosa. Otro método en Cylider ( toString() ) llama a ese método getArea() .
  2. Luego, Chylidar con un tipo secundario ( Piston ) y anuló la función getArea() para hacer algo diferente.
  3. Ahora, cuando se está en el código de Cylider clase CLLS la getArea() método, se espera que use el Cylider versión de getArea() debido a que el código fue escrito en la misma clase, pero en realidad se utilizó el overriden Piston versión de getArea() porque el objeto sobre el que lo estaba llamando en realidad era un Piston .

Esto no es realmente un error o incluso un problema para resolver, es solo una función de cómo Java resuelve las llamadas a métodos. Escogerá el más específico dado el tipo real del objeto con el que está trabajando (incluso si no es obvio en el momento de la compilación cuál sería ese tipo) no el que está escrito más cerca de la vista de la persona que llama.

Realmente no hay una manera de evitar esto. Tomaría esto como una señal de que su diseño es malo, o al menos no idiomático. La anulación de funciones está pensada para que usted brinde una forma diferente y más correcta de calcular la misma idea para un tipo diferente , no solo como una forma de reutilizar los nombres de las funciones.

El cambio más fácil probablemente sería simplemente crear un nuevo método en Cylinder llamado getCylinderArea() . Cylider.getArea() podría llamar a esta función de manera predeterminada, pero podría llamarla explícitamente en Cylider.toString() si desea que esa función solo use el método de cálculo de área de cilindro simple.

Alternativamente, Quizás Piston no debería ser realmente un subtipo de Cylinder porque, a pesar de que comparten algunas características, un Piston no puede ser sustituido por un cilindro genérico en cualquier lugar donde usaría un cilindro, por ejemplo, al calcular el área. Consulte el Principio de sustitución para obtener más información.

Sin embargo, personalmente, tiendo a evitar la herencia por completo por este tipo de razón. En realidad, recomendaría simplemente usar interfaces y una jerarquía plana en este caso.

Este hilo de StackOverflow puede ser interesante si desea obtener más detalles sobre cómo llamar a los súper métodos.

Related