3

所以我在 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 不应该带参数!作业纸上有错字吗?

4

7 回答 7

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 的冗长而苦苦挣扎,您必须在其中显式地将构造函数参数复制到实例字段上才能实现封装。其他语言更优雅地解决了这个问题,构造函数可以与类本身一起隐式定义。但是,它们仍将转换为与上述 Java 代码等效的内容。例如:

斯卡拉:

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/

于 2013-06-26T10:33:08.177 回答
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));

    }

}
于 2013-06-26T10:36:26.740 回答
0

在你的主要功能有这样的

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

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

public void getChillingTime(double wineTemp, double preferredTemp, double chillTemp)
{
//do something
}
于 2013-06-26T10:36:12.490 回答
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();
    }

我推荐第二种方法,这是标准方法。

于 2013-06-26T10:32:15.060 回答
0

您在构造函数中使用的wineTemp内容需要设置在某个地方,以便在getChillingTime方法中可以访问它。

建议修复

    public class WineChiller {

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

        ...
于 2013-06-26T10:32:55.660 回答
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() {
        // ...
    }
}
于 2013-06-26T10:37:58.540 回答
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();

    }
于 2013-06-26T10:36:31.063 回答