我正在创建一个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参数传递给构造函数,而是使用方法返回值来代替实例变量的值。
答案 0 :(得分:3)
语法上没问题,但是你不应该从构造函数中调用覆盖(public / protected non-final)方法。如果有人覆盖它,它可能会破坏你的对象的构造。从构造函数调用辅助方法很好,只需将其设为私有或最终。
this.bmr = calcBMR()
与...相同
bmr = calcBMR()
说bmr.calcBMR()
没有意义,因为calcBMR
方法位于User
对象上。 bmr
是int
,因此它没有名为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
。
我想在此处添加一点,bmr
是Health
的{{1}}相关参数之一,因此您应该在单独的类中收集所有这些参数,其中包括其中包含Person
,bodyFat
,bmr
等,并在medicalAge
的构造函数中传递User
Object
。因此,最终class
参数只能由有效用户构建。
答案 2 :(得分:0)
我认为你的方式还可以。但是,如果您使用的所有属性都是最好的,那就是私有"并为他们获得/设定。所以,当另一个班级扩展你的班级时,我们不必担心凌乱的事情。使用calcTDEE方法,我认为你只需要将你的bmr属性放在其中,因为它是在你的构造函数中设置的。因此,在您调用此方法时,bmr具有正确的值。
public int calcTDEE() {
return (int) Math.round(bmr * activityMultiplier);
}
希望得到这个帮助。