Java与构造函数

时间:2015-09-04 01:31:33

标签: 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 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行所做的)。这个编程结构好吗?即创建User对象时,年龄,性别,身高和体重都存储在变量中, THEN 在构造函数中调用一个方法来计算和存储另一个值。

有更好的方法吗?如果没有,我是否需要this.bmr = calcBMR()bmr = calcBMR()好吗?

请注意,User对象是在单独的类中创建的。我之所以感到困惑的原因是因为我没有将bmr参数传递给构造函数,而是使用方法返回值来代替实例变量的值。

3 个答案:

答案 0 :(得分:3)

语法上没问题,但是你不应该从构造函数中调用覆盖(public / protected non-final)方法。如果有人覆盖它,它可能会破坏你的对象的构造。从构造函数调用辅助方法很好,只需将其设为私有或最终。

this.bmr = calcBMR()与...相同 bmr = calcBMR()

bmr.calcBMR()没有意义,因为calcBMR方法位于User对象上。 bmrint,因此它没有名为calcBMR的方法

您是否使用this是您的偏好问题。如果你有一个名为bmr的局部变量,那么它才真正有所作为,然后你明确地调用实例变量而不是本地变量。通常,使用具有相同名称的本地变量和实例变量会让人感到困惑。

你的calcTDEE方法虽然有点偏。你可以使用bmr的值,而不是传递它或重新计算它,所以它将是

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

答案 1 :(得分:0)

  

最好将计算与构造分开。

我个人认为我们应该避免这样做。据我所知,任何使用Class构建Object的人都不会意识到bmr也是通过查看此特定构造函数在User中计算的事实,直到他查看代码。在构建API时,您应该让将要使用User的消费者更具可读性,除了它完全有效。此外,正如Jeff Storey所建议的,如果您不希望用户Object使用您的calcBMR,则应该private

我想在此处添加一点,bmrHealth的{​​{1}}相关参数之一,因此您应该在单独的类中收集所有这些参数,其中包括其中包含PersonbodyFatbmr等,并在medicalAge的构造函数中传递User Object。因此,最终class参数只能由有效用户构建。

答案 2 :(得分:0)

我认为你的方式还可以。但是,如果您使用的所有属性都是最好的,那就是私有"并为他们获得/设定。所以,当另一个班级扩展你的班级时,我们不必担心凌乱的事情。使用calcTDEE方法,我认为你只需要将你的bmr属性放在其中,因为它是在你的构造函数中设置的。因此,在您调用此方法时,bmr具有正确的值。

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

希望得到这个帮助。