Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/variables/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java与构造函数中的参数传递混淆_Java_Variables_Constructor - Fatal编程技术网

Java与构造函数中的参数传递混淆

Java与构造函数中的参数传递混淆,java,variables,constructor,Java,Variables,Constructor,我正在创建一个BMR计算器,我有一个名为User的类。此类包含用于计算BMR的所有方法,以及将用户数据(年龄、性别、体重、身高)打包在一起的构造函数 代码是: public class User { int age; String gender; // todo: use an Enum double height; // height stored in cm, weight in kg (so if user enters in feet/lbs, conversions are done

我正在创建一个BMR计算器,我有一个名为User的类。此类包含用于计算BMR的所有方法,以及将用户数据(年龄、性别、体重、身高)打包在一起的构造函数

代码是:

public class User {

int age;
String gender; // todo: use an Enum
double height; // height stored in cm, weight in kg (so if user enters in feet/lbs, conversions are done to cm/kg and *THEN* passed through to constructor below)
double weight;
double activityMultiplier; // todo: use an Enum  (possibly)
int bmr;


public User(int age, String gender, double height, double weight,
    double activityMultiplier) {
    this.age = age;
    this.gender = gender;
    this.height = height;
    this.weight = weight;
    this.activityMultiplier = activityMultiplier;

    bmr = calcBMR();
}

/**
 * If user input is correct, this method will calculate the BMR value of the user given their input and measurement choices.
 * 
 * @param None
 * @return BMR Value
 */
public int calcBMR() {
    int offset = gender.equals("M") ? 5 : -161;
    // This is the body of the calculations - different offset used depending on gender. Conversions to kg and cm done earlier so no conversions needed here.
    // The formula for male and female is similar - only the offset is different.
    return (int) (Math.round((10 * weight) + (6.25 * height) - (5 * age) + offset)); // This is the Miffin St-Jeor formula, calculations done in cm/kg
    }

/**
 * If the user selects the TDEE option, this method will be executed after the calcBMR() method. 
 * A value from the calcBMR() method will be passed down to this method, and is multiplied
 * by the activity level parameter passed into this method.
 * 
 * @param bmr (output from calcBMR() method
 * @return TDEE Value
 */
public int calcTDEE(int bmr) {
    return (int) Math.round(calcBMR() * activityMultiplier);
}

}
我担心的是,我不确定在构造函数(
bmr=calcBMR()
)中初始化bmr值的方式是否正确。我无法计算bmr,直到用户的年龄、性别、身高和体重被记录并存储在变量中(上面5行就是这么做的)。这个编程结构可以吗?即,当创建用户对象时,年龄、性别、身高和体重存储在变量中,然后在构造函数中调用一个方法来计算和存储另一个值

有更好的方法吗?如果没有,我需要执行
this.bmr=calcBMR()
还是
bmr=calcBMR()
正常


注意,用户对象是在一个单独的类中创建的。我之所以感到困惑,主要是因为我没有将bmr参数传递给构造函数,而是使用方法返回值来初始化实例变量的值。

语法上没有问题,但是不应该从构造函数调用可重写(公共/受保护的非最终)方法。如果有人覆盖它,它可能会破坏对象的构造。从构造函数调用helper方法很好,只需将其设置为私有或最终

this.bmr=calcBMR()
bmr=calcBMR()

bmr.calcBMR()
没有意义,因为
calcBMR
方法位于
User
对象上
bmr
是一个
int
,因此它没有名为
calcBMR

您是否使用
取决于您的喜好。只有当您有一个名为
bmr
的局部变量,然后显式调用实例变量而不是局部变量时,这才真正起作用。一般来说,使用相同名称的局部变量和实例变量很容易混淆

不过,您的
calcTDEE
方法有点不合适。您可以只使用
bmr
的值,而不传入或重新计算它,因此

public int calcTDEE() {
    return (int) Math.round(bmr * activityMultiplier);
}
最好将计算与构造分开

我个人认为我们应该避免这样做。根据我的说法,任何使用
构造
对象
的人都不会意识到
bmr
也在
用户
中通过查看此特定构造函数进行计算,直到他查看代码为止。当您构建
API
时,您应该让将要使用您的
User
的消费者更易于阅读,除此之外,它是完全有效的。此外,正如所建议的,如果您不希望用户
对象
s使用您的
calcBMR
,您应该将其设置为
私有


我想在这里补充一点,
bmr
Person
Health
相关参数之一,因此您应该在单独的类中收集所有此类参数,包括
bodyFat
bmr
medicalAge
等,并将您的
用户
对象
传递给该
类的构造函数
。因此,
Health
参数最终只能由有效的用户来构造。

我认为您的方法是可以的。但是,如果您使用的所有属性都是“私有”的,并且具有get/set属性,则效果更好。所以,当另一个类扩展您的类时,我们不必担心混乱的事情。对于calcTDEE方法,我认为您只需要将bmr属性放入其中,因为它是在构造函数中设置的。因此,在调用此方法时,bmr具有正确的值

public int calcTDEE() {
    return (int) Math.round(bmr * activityMultiplier);
}

希望这能有所帮助。

谢谢你的评论。对不起,当我写
bmr.CalcBMR()
时,我的意思是
bmr=CalcBMR
。编辑我的帖子。因此,您唯一的建议是将
calcBMR()
方法设置为最终方法?这到底是做什么的?或者更可能的是,如果您只是从类内部调用它,则将其设置为私有。通过使它成为最终的或私有的,这意味着没有其他人可以改变它的行为。您可以创建一个覆盖calcBMR()的子类,然后更改您的计算(假设您不希望这样)。您还可以将其设置为私有,然后使用getBMR()方法,让人们只获取值。我假设您实际上不希望人们调用calcBMR(),您只希望他们获取值,对吗?是的,对。我唯一调用
calcBMR()
我自己的地方是在构造函数中,主类只创建一个名为user1的用户对象,并将bmr引用为
user1.bmr
。我将使这个方法私有,因为它只从用户类调用,听起来不错吧?谢谢:)事实上,我已经将其保留为
公共
,但将其设置为
最终版
,因此,如果需要修改代码,我仍然可以从
BmrMain
类调用它。将final添加到方法签名中是否足够可行,以使其不可重写?除了Jeff的优点之外,我建议您将所有字段设置为私有,并为每个字段提供getter方法。如果没有这一点,外部代码可以在不重新计算bmr的情况下更改某些字段值。我喜欢这一建议,但我还没有准备好使用bodyfat计算器等。我想当我添加更多选项时,我只会将基础存储在
User
类中,并创建另一个类,该类可以包含计算BMR、TDEE、体脂、宏(?)等的所有方法,以及可以存储值的构造函数。这就是你想说的吗?好的,你认为最好的方法是从
Health
类调用方法(即
calcBodyFat()
calcBMR