Java初学者:Sphere类

时间:2017-04-10 14:01:34

标签: java setter

我正在寻找下面发布的代码的帮助。这是一个问题,我必须制作一个球类和另一个类来测试它。我几乎了解一切,但唯一让我感到害怕的是设置新的直径并获得新的音量。当我设置一个新的直径时,直径很容易改变,但当我尝试再次运行音量时,它只使用旧的直径而不是新的直径。请帮忙谢谢!

public class Sphere {
private double sphDiam, volume, surfArea;
private final double VOL_RELAY = 4.0 / 3.0;
private final int SURF_CONST = 4;

public Sphere(double sphDiam) {
    this.sphDiam = sphDiam;
    setVolume();
    setSurfaceArea();
}

public double getDiam() {
    return sphDiam;
}

public void setDiam(double sphDiam) {
    this.sphDiam = sphDiam;
}

public double getVolume() {
    return volume;
}

public void setVolume() {
    volume = Math.pow(sphDiam / 2, 3) * Math.PI * VOL_RELAY;
}

public double getSurfaceArea() {
    return surfArea;
}

public void setSurfaceArea() {
    surfArea = Math.pow(sphDiam / 2, 2) * Math.PI * SURF_CONST;
}

public String toString() {
    return "Sphere diameter: " + sphDiam + "\nSphere Volume: " + volume + "\nSphere Surface Area: " + surfArea; 
}
}

public class MultiSphere {

public static void main(String[] args) {

    Sphere sph1 = new Sphere(10.5);
    Sphere sph2 = new Sphere(8.4);
    Sphere sph3 = new Sphere(20.1);

    sph1.setDiam(3.2);
    System.out.println(sph1.getDiam());
    System.out.println(sph1.getVolume());
    System.out.println(sph1.getSurfaceArea());
    System.out.println(sph1);
    System.out.println();
    sph1.setDiam(2.5);
    System.out.println(sph1.getDiam());
    System.out.println(sph1.getVolume());
    System.out.println(sph1.getSurfaceArea());
    System.out.println(sph1);
    System.out.println();


    System.out.println(sph2.getDiam());
    System.out.println(sph2.getVolume());
    System.out.println(sph2.getSurfaceArea());
    System.out.println(sph2);
    System.out.println();

    System.out.println(sph3.getDiam());
    System.out.println(sph3.getVolume());
    System.out.println(sph3.getSurfaceArea());
    System.out.println(sph3);
    System.out.println();
}
}

2 个答案:

答案 0 :(得分:4)

当您“设置直径”时,您正在更改形状的尺寸。但你永远不会更新音量。因此volume值仍然反映了之前的维度。

我想你的setter应该只更新那个值。像这样:

public void setDiam(double sphDiam) {
    this.sphDiam = sphDiam;
    setVolume();
}

然而...... 如果您更进一步,可以稍微简化一下对象。查看您的setVolume()方法...它不接受值。它实际上并不是设置,它只是重新计算动态值。该值根本不需要存储,只能在getter中计算。

所以完全摆脱volume变量,完全摆脱setVolume()方法,然后将计算放在getter中:

public double getVolume() {
    return Math.pow(sphDiam / 2, 3) * Math.PI * VOL_RELAY;
}

对任何其他计算值重复。

无需存储容易计算的值,因为您承担了保持值同步的责任。这是导致你遇到这个问题的原因。球体需要的唯一值是半径(或直径)。所有其他值都来自于此。如果您存储其他值,那么基本上您将在多个位置存储相同的信息。最好尽可能避免这种情况。

答案 1 :(得分:0)

您只在创建球体时设置体积和曲面。 如果您没有告诉程序执行此操作,设置新直径不会自动重新调整音量和曲面。

有两种解决方案:

  • 每次更改直径时重新计算表面和体积:

    public Sphere(double sphDiam) {
        this.sphDiam = sphDiam;
        setVolume();
        setSurfaceArea();
    }
    
    public double getDiam() {
        return sphDiam;
    }
    
    public void setDiam(double sphDiam) {
        this.sphDiam = sphDiam;
        setVolume();
        setSurfaceArea();
    }
    
    public double getVolume() {
        return volume;
    }
    
    public void setVolume() {
        volume = Math.pow(sphDiam / 2, 3) * Math.PI * VOL_RELAY;
    }
    
    public double getSurfaceArea() {
        return surfArea;
    }
    
    public void setSurfaceArea() {
        surfArea = Math.pow(sphDiam / 2, 2) * Math.PI * SURF_CONST;
    }
    
  • 每次获取时计算值,这样,您就可以删除变量volumesurface以及相关的设置器:

    public Sphere(double sphDiam) {
        this.sphDiam = sphDiam;
    }
    
    public double getDiam() {
        return sphDiam;
    }
    
    public void setDiam(double sphDiam) {
        this.sphDiam = sphDiam;
        setVolume();
        setSurfaceArea();
    }
    
    public double getVolume() {
        return Math.pow(sphDiam / 2, 3) * Math.PI * VOL_RELAY;
    }
    
    public double getSurfaceArea() {
        return Math.pow(sphDiam / 2, 2) * Math.PI * SURF_CONST;
    }