为什么我的构造函数参数没有被传递?

Why are my constructor arguments not passed?

这是我的class。在底部的主要方法中,我在构造函数中传递了两个参数 (int numTriangles, double radius) 作为 (8,1)。在顶部 radius 和 numTriangles 声明的变量应该采用这些值,因为我的构造函数分配它们然后运行计算。但是,当 twoTheta 被计算为此时 numTriangles 为零时,我得到除以零的错误。为什么会这样,我该如何解决?谢谢。

package Triangles;

public class Triangles {

    double radius;
    int numTriangles;
    double twoTheta = 360/numTriangles;
    double theta = twoTheta / 2;
    double base;
    double height;
    double result;
    double halfTriangleArea;
    double triangleArea;
    double area;

    public Triangles(int numTriangles, double radius) {
        this.numTriangles = numTriangles;
        this.radius = radius;
        runCalculation();
    }

    // My methods

    public double calculateBase() { // SOH
        double thetaToRadians = Math.toRadians(theta);
        double base = Math.sin(thetaToRadians) / radius;
        return base;
    }

    public double calculateHeight() { // CAH
        double thetaToRadians = Math.toRadians(theta);
        double height = Math.cos(thetaToRadians) / radius;
        return height;
    }

    public double checkPythag(double base, double height) {
        double a = base;
        double b = height;
        double result = Math.sqrt(a*a + b*b);
        return result;
    }

    public double calculateArea(double base, double height) {
        double halfTriangleArea = (0.5) * base * height;
        return halfTriangleArea;
    }

    public double runCalculation() {
        base = calculateBase();
        height = calculateHeight();
        result = checkPythag(base, height);
        halfTriangleArea = calculateArea(base, height); 
        triangleArea = 2 * halfTriangleArea;
        // C = Pi * D = Pi * 2 * r
        // A = Pi * r.^2
        area = numTriangles * triangleArea;
        // Substitute Pi for X
        // area = X * r.^2
        // if r is 1
        // area = X
        return area;
    }

    // Runnable

    public static void main(String[] args) { // create an instance of class to run in main
        Triangles triangles = new Triangles(8, 1);
        System.out.println("radius: " + triangles.radius);
        System.out.println("numTriangles: " + triangles.numTriangles);
        System.out.println("twoTheta " + triangles.twoTheta);
        System.out.println("theta " + triangles.theta);
        System.out.println("base: " + triangles.base);
        System.out.println("height: " + triangles.height);
        System.out.println("checkPythag " + triangles.result + " | " + triangles.radius);
        System.out.println("halfTriangleArea: " + triangles.halfTriangleArea);
        System.out.println("triangleArea: " + triangles.triangleArea);
        System.out.println("Approximation of Pi by triangles: " + triangles.area);
    }   
}

class 属性在调用构造函数之前初始化。
因此,属性 numTriangles 首先设置为 0。之后执行 double twoTheta = 360/numTriangles;
之后调用构造函数。
这就是你得到错误的原因。

因此,不要直接初始化twoThetatheta属性,而是在设置numTrianglesradius属性后让构造函数处理它。

致电runCalculation();

之后
Triangles triangles = new Triangles(8, 1);

在您的 main 方法中。

让构造函数完成。

您可以像这样更改代码以避免错误。

public Triangles(int numTriangles, double radius) {
        this.numTriangles = numTriangles;
        this.radius = radius;           
        initialize();
        runCalculation();
    }

    private void initialize()
    {
      twoTheta = 360/numTriangles;
      theta = twoTheta / 2;      
    }

您从构造函数中调用 runCalculation() - 此时 twoTheta 已为其分配了默认值(原始值是 0,甚至在调用构造函数之前就已分配默认值)。有两种简单的方法可以解决您的问题:

  1. 您应该从构造函数外部调用 runCalculation() 以确保所有字段都被初始化为默认值以外的值(您指定的值)

  2. 您可以在 构造函数中初始化 twoThetatheta,然后 调用 runCalculation()


如果您想使用第一个选项 - 像这样更改您的 main 方法以查看您期望的结果:

public static void main(String[] args) {
    Triangles triangles = new Triangles(8, 1);
    triangles.runCalculation();
    ...
}

您还应该从构造函数的主体中删除对 runCalculation() 的调用。


如果您选择第二种方式解决您的问题,只需在构造函数主体中的 runCalculation() 之前初始化 thetatwoTheta

public Triangles(int numTriangles, double radius) {
    this.numTriangles = numTriangles;
    this.radius = radius;
    this.twoTheta = 360/this.numTriangles;
    this.theta = this.twoTheta/2;
    runCalculation();
} 

您可能想查看 here 官方 Java 教程以查看分配给基本类型的默认值列表并阅读更多相关信息(顺便说一句,对象被分配默认为 null)。

因为这些定义是在 创建 class 时执行的,而不是在 实例化对象 时执行的。此外,当您声明但不分配半径或 numTriangles 时,将使用 默认值 0。对于任何原始类型(double、int、float 等),默认值为 0,对于任何其他类型(String、Triangle,...),默认值为 null。

您应该只在 class 中声明它们并在构造函数中分配它们。

double radius;
int numTriangles;
double twoTheta;

public Triangle(double radius, int numTriangles) {
    this.radius = radius;
    this.numTriangles = numTriangles;
    this.twoTheta = 360 / numTriangles;
}

正如多个答案指出的那样,twoTheta(以及 theta)在调用构造函数之前被初始化,因此出现错误。

我建议你在 twoThetatheta 构造函数中初始化。

 public Triangles(int numTriangles, double radius) {
    this.numTriangles = numTriangles;
    this.radius = radius;
    //Initialize twoTheta
    this.twoTheta = 360/this.numTriangles;
    this.theta = this.twoTheta/2;
    runCalculation();
}