Java:为什么我的变量不能传递给我的方法可用的构造函数?

时间:2013-06-26 10:30:03

标签: java class methods

所以我在main中声明了一些变量并创建了一个新对象;将变量作为参数传递给构造函数。现在,当我在类中调用一个方法时,我会认为这些变量可以被方法访问,而不必将它们作为参数传递给它。这不是这样吗?

以下是代码:

import java.util.Scanner;

public class Step2_lab11 {

    public static void main(String[] args) {

        final int TAO = 50;
        final double DELTA_MINUTES = 0.1;

        System.out.println("VINETS AVKYLNINGSTID \n");
        System.out.println("Ange vinets temperatur:");

        Scanner userIn = new Scanner(System.in);
        double wineTemp = userIn.nextDouble();

        System.out.println("Vinets önskade temperatur:");
        double preferredTemp = userIn.nextDouble();

        System.out.println("Kylens/frysens temperatur:");
        double chillTemp = userIn.nextDouble();

        WineChiller wineChiller = new WineChiller(wineTemp, preferredTemp, chillTemp);

    }

}

以下是WineChiller.java类:

public class WineChiller {

    public WineChiller(double wineTemp, double preferredTemp, double chillTemp) {
        getChillingTime();

    }

    public void getChillingTime() {

        while(wineTemp>preferredTemp)
        {
            elapsedTime += DELTA_MINUTES;
            double dT = (wineTemp - chillTemp) * DELTA_MINUTES  / TAO;
            wineTemp -= dT;
        }
        System.out.println(Math.round(elapsedTime));

    }

}

为什么getChillingTime无法将wineTemp等解析为变量?

编辑添加:非常感谢指点家伙。但还有一个警告!说明似乎暗示WineChiller类应该只包含构造函数和方法getChillingTime,并且getChillingTime不应该带参数!作业文件中是否有拼写错误?

7 个答案:

答案 0 :(得分:5)

虽然在Scala或Ceylon (见下文)等语言中可能会出现这种情况,但在Java中,必须将构造函数参数明确地分配给实例变量。因此:

public class WineChiller {

    double wineTemp;
    double preferredTemp;
    double chillTemp;

    public WineChiller(double wineTemp, double preferredTemp, double chillTemp) {
        this.wineTemp = wineTemp;
        this.preferredTemp = preferredTemp;
        this.chillTemp = chillTemp;

        getChillingTime();
    }

构造函数参数仅在构造函数的范围内可见。构造函数调用getChillingTime()这一事实无关紧要。如果希望它们在WineChiller实例的范围内可见,则必须在该类中创建成员。然后,该类的所有方法都可以访问实例成员。

无论如何,我强烈建议您仔细阅读Java教程。这是一个:

http://docs.oracle.com/javase/tutorial

其他JVM语言的构造函数

我认为你主要是在努力解决Java的冗长问题,你必须将构造函数参数显式复制到实例字段中才能实现encapsulation。其他语言更优雅地解决了这个问题,其中构造函数可以与类本身一起隐式定义。但是,它们仍将转换为与上述Java代码等效的内容。例如:

Scala的:

class Greeter(message: String) {
    def SayHi() = println(message)
}

val greeter = new Greeter("Hello world!")
greeter.SayHi()

此处的示例:http://joelabrahamsson.com/learning-scala-part-four-classes-and-constructors/

锡兰

class Point(Float x, Float y) { ... }
object origin extends Point(0.0, 0.0) {}

此处的示例:http://ceylon-lang.org/documentation/1.0/spec/html_single/

答案 1 :(得分:2)

  

传递给方法的变量范围是方法本身

换句话说,一旦方法执行结束,传递给方法的变量就会被破坏(垃圾收集)。

构造函数是一种特殊的方法,用于创建该类型的实例。

由于没有创建了传递给类型中构造函数的变量的副本,因此它们会丢失,从而导致错误。

要使您的代码正常工作,声明您班级中的字段

public class WineChiller {

    private double wineTemp;
    private double preferredTemp;
    private double chillTemp;

    public WineChiller(double wineTemp, double preferredTemp, double chillTemp) {
        this.wineTemp = wineTemp;
        this.preferredTemp = preferredTemp;
        this.chillTemp = chillTemp;
        getChillingTime();

    }

    public void getChillingTime() {

        while(wineTemp>preferredTemp)
        {
            elapsedTime += DELTA_MINUTES;
            double dT = (wineTemp - chillTemp) * DELTA_MINUTES  / TAO;
            wineTemp -= dT;
        }
        System.out.println(Math.round(elapsedTime));

    }

}

答案 2 :(得分:0)

  

为什么getChillingTime无法将wineTemp等解析为变量?

不是局部变量如何运作。 wineTemp仅限于WineChiller constructor内。您必须将其作为参数传递给getChillingTime()方法并使用它,或者将其设为您班级的实例变量

 public WineChiller(double wineTemp, double preferredTemp, double chillTemp) {
        getChillingTime(wineTemp);
    }
 public void getChillingTime(double wineTemp) {

public class WineChiller {
private double wineTemp;
    public WineChiller(double wineTemp, double preferredTemp, double chillTemp) {
        this.wineTemp = wineTemp;
        getChillingTime();
    }

我推荐标准方式的第二种方法。

答案 3 :(得分:0)

你需要在构造函数中设置wineTemp,以便在getChillingTime方法中可以访问它。

建议修复

    public class WineChiller {

        private double wineTemp;
        public WineChiller(double wineTemp, double preferredTemp, double chillTemp) {
            this.wineTemp = wineTemp;
            ...
        }

        ...

答案 4 :(得分:0)

在你的主要功能中有这样的

WineChiller wineChiller = new WineChiller();
wineChiller.getChillingTime(wineTemp, preferredTemp, chillTemp);

在你的WineChiller类中有获取这些输入的方法

public void getChillingTime(double wineTemp, double preferredTemp, double chillTemp)
{
//do something
}

答案 5 :(得分:0)

作为参数传递给方法的变量仅对该方法是局部的。如果您希望在另一种方法中使用它们,则必须将它们存储为实例变量,或者将它们作为参数再次传递。

public class WineChiller {

    double mWineTemp;
    double mPreferredTemp;
    double mChillTemp;

    public WineChiller(double wineTemp, double preferredTemp, double chillTemp) {

        mWineTemp = wineTemp;
        mPreferredTemp = preferredTemp;
        mChillTemp = chillTemp;

        getChillingTime();

    }

答案 6 :(得分:0)

要么传递参数,因为参数的范围不会超出方法本身

public WineChiller(double wineTemp, double preferredTemp, double chillTemp) {
    getChillingTime(wineTemp, preferredTemp, chillTemp); // pass the arguments
}

public void getChillingTime(
            double wineTemp, double preferredTemp, double chillTemp) {
    // ...
}

或者,将它们另存为实例成员字段(推荐),可以从每个实例方法自动访问

public class WineChiller {

    // instance member fields
    private double wineTemp;
    private double preferredTemp;
    private double chillTemp;

    public WineChiller(double wineTemp, double preferredTemp, double chillTemp) {
        this.wineTemp = wineTemp;
        this.preferredTemp = preferredTemp;
        this.chillTemp = chillTemp;

        getChillingTime();
    }

    public void getChillingTime() {
        // ...
    }
}