【问题标题】:Problems with toString() and Overriding MethodstoString() 和覆盖方法的问题
【发布时间】:2020-02-27 01:07:25
【问题描述】:

我对这段代码有疑问。它没有正确计算面积。我需要它来计算气缸/活塞的横截面积和气缸的表面积。如果您注意到输出,当我使用 getArea() 方法时,这两个值似乎是相同的值。 Java 对使用什么 getArea() 感到困惑?强文本我试图用 getArea() [横截面积] 覆盖 getArea() [表面积] 但它不起作用?

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+" .";
  }
}

如果我输入半径为 5 且高度为 10,这是输出。

输入半径,然后是高度,如果圆柱体被填充 (有填充则输入1,不填充则输入0,然后输入颜色 5 10 1 蓝色

这是一个圆柱体及其属性

颜色为:蓝色,形状填充:true 半径= 10.0 高度= 5.0 圆柱体总表面积= 942.0 体积= 1570.0。

这是小活塞

颜色:黄色,形状填充:false 半径= 2.5 高度= 10.0 圆柱体总表面积= 19.625 体积= 196.25。 t活塞截面积=19.625轴长=1.0 压力=1.0。

这是大活塞

颜色是:红色,形状填充是:true Radius= 1234.4 Height= 55.6 圆柱体总表面积= 4784554.150400002 体积= 2.6602121076224005E8。 活塞截面积=4784554.150400002轴长=1200.0 压力=12.3.

【问题讨论】:

  • 请添加Java标签。

标签: java overriding tostring


【解决方案1】:

澄清一下——情况似乎是这样的:

  1. 你有一个类 (Cylider),它定义了一个方法 (getArea()) 来做一件事。 Cylider (toString()) 上的另一个方法调用 getArea() 方法。
  2. 然后,您使用子类型 (Piston) 对 Chylidar 进行子类化并覆盖 getArea() 函数以执行不同的操作。
  3. 现在,当您在Cylider 类中编写代码时,会调用getArea() 方法,您希望它使用Cylider 版本的getArea() 因为代码是在同一个类中编写的,但实际上它使用了 getArea() 的覆盖 Piston 版本因为您调用它的对象实际上是活塞

这并不是真正的错误,甚至不是要解决的问题——它只是 Java 如何解析方法调用的一个函数。它会根据您正在使用的对象的实际类型选择最具体的那个(即使在编译时该类型并不明显)不是写在最靠近调用者视线的地方。

真的没有办法解决这个问题。我认为这表明你的设计很糟糕——或者至少不是惯用的。重写函数旨在为您提供一种不同的、更正确的方法来计算 不同类型相同想法,而不仅仅是作为重用函数名称的一种方式。

最简单的更改可能是在Cylinder 上创建一个名为getCylinderArea() 的新方法。 Cylider.getArea() 可以默认调用此函数,但如果您希望该函数仅使用普通 Cylinder 计算面积的方法,则可以在 Cylider.toString() 中显式调用它。

另外,Maybe Piston 实际上不应该是 Cylinder 的子类型,因为即使它们有一些共同的特征,活塞也不能在您使用气缸的任何地方替代通用气缸 - 例如,计算面积时。查看Substitution Principle 了解更多信息。

不过,出于这种确切的原因,我个人倾向于完全远离继承。在这种情况下,我实际上建议只使用接口和平面层次结构。

This StackOverflow thread 如果您想了解有关调用超级方法的更多详细信息,可能会很有趣。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2012-10-20
    • 2018-01-10
    • 2018-07-05
    • 1970-01-01
    • 1970-01-01
    • 2015-08-28
    • 1970-01-01
    • 2011-11-30
    相关资源
    最近更新 更多