我正在查看这个答案,以便在java中处理单元。这个概念对我来说很有趣,只是我不喜欢它必须是每个有质量的对象,而不是单独封装一个Mass类,这样就不需要重复这种模式了。这就是我想出来的。
public class Main
{
public static void main(String args[]){
Mass x = Mass.from_oz(2.3);
System.out.println("x in kg: " + x.get_kg());
System.out.println("x in oz: " + x.get_oz());
Mass y = Mass.from_lb(1.2);
System.out.println("y in kg: " + y.get_kg());
System.out.println("y in lb: " + y.get_lb());
Mass z = Mass.add(x, y);
System.out.println("x + y in kg: " + z.get_kg());
z.add(Mass.from_kg(2.0));
System.out.println("x + y + 2.0kg in kg: " + z.get_kg());
}
}
public class Mass{
private double mass;
private static double LB_PER_KG = 2.20462;
private static double OZ_PER_LB = 16;
private static double lb_to_kg(double value){
return value * (1/LB_PER_KG);
}
private static double kg_to_lb(double value){
return value * (LB_PER_KG);
}
private static double kg_to_oz(double value){
return value * (LB_PER_KG*OZ_PER_LB);
}
private static double oz_to_kg(double value){
return value * (1/(LB_PER_KG*OZ_PER_LB));
}
public double get_kg(){
return this.mass;
}
public double get_lb(){
return kg_to_lb(this.mass);
}
public double get_oz(){
return kg_to_oz(this.mass);
}
public void set_kg(double value){
this.mass = value;
}
public void set_lb(double value){
this.mass = lb_to_kg(value);
}
public void set_oz(double value){
this.mass = oz_to_kg(value);
}
private Mass(double value){
set_kg(value);
}
public static Mass from_kg(double value){
return new Mass(value);
}
public static Mass from_lb(double value){
return new Mass(lb_to_kg(value));
}
public static Mass from_oz(double value){
return new Mass(oz_to_kg(value));
}
public Mass add(Mass rhs){
this.mass += rhs.mass;
return this;
}
public Mass sub(Mass rhs){
this.mass -= rhs.mass;
return this;
}
public Mass div(Mass rhs){
this.mass *= rhs.mass;
return this;
}
public Mass mul(Mass rhs){
this.mass /= rhs.mass;
return this;
}
public static Mass add(Mass lhs, Mass rhs){
return new Mass(lhs.mass).add(rhs);
}
public static Mass sub(Mass lhs, Mass rhs){
return new Mass(lhs.mass).sub(rhs);
}
public static Mass mul(Mass lhs, Mass rhs){
return new Mass(lhs.mass).mul(rhs);
}
public static Mass div(Mass lhs, Mass rhs){
return new Mass(lhs.mass).div(rhs);
}
}除了对这些问题的回答之外,还需要寻求任何批评:
发布于 2018-08-14 02:55:37
对于Mass,我会定义一些常量。
public final static Mass kg = new Mass(1);
public final static Mass lb = new Mass(1/2.2, kg);
public final static Mass oz = new Mass(1/16.0, lb);并使用传入的“to”(和“from”)单元定义您的转换。
public double in(Mass unit) {
return mass / unit.mass;
}
public static double convert(double quantity, Mass from, Mass to) {
return quantity * from.mass / to.mass;
}当然,您需要删除“set”成员,并使Mass成为一个常量值类。
private final double mass;
public Mass(double kg) {
mass = kg;
}
public Mass(double quantity, Mass unit) {
mass = quantity * unit.mass;
}新单位只意味着定义新的类常量。
Mass weight = new Mass( 100, Mass.kg );
double pounds = weight.in( Mass.lb );
double ounces = weight.in( Mass.oz );如注释中所述,如果跟踪quantity类中每个单元维度的大小,则可以将其扩展为完整的单位计算器。
发布于 2018-08-18 19:59:39
除了AJNeufeld的回答:
您有两个add()方法。
public Mass add(Mass rhs){
this.mass += rhs.mass;
return this;
}
public static Mass add(Mass lhs, Mass rhs){
return new Mass(lhs.mass).add(rhs);
}第一个原因可能是严重调试会话的原因,因为您修改了“此”块的内容,而从方法签名(返回一个大规模实例)中,调用方可能期望创建一个新的Mass实例,并且两个输入实例保持不变。Java程序员通常会期望他们知道这种行为,例如Java的BigInteger.add()方法。
在用Java进行编程时,总是值得考虑对象标识。通常,您应该只提供保持当前对象标识不变的方法。例如,如果你的个人实例代表唐纳德·特朗普,你不应该允许类似donaldTrump.setName("Barack Obama");这样的东西,因为这从根本上改变了该实例的身份。它完全不是同一个人,所以它不应该是同一个Java实例。
在您的示例中,Mass的实例表示一些大量值。查看使用当前API的下列代码行:
Mass mass10kg = Mass.from_kg(10.0);
mass10kg.add(Mass.from_kg(15.0));第二行修改以前表示10公斤的质量实例,现在表示25公斤。还是一样的质量吗?当然不是,所以我建议不要那样做。
对于Java实例,最好将定义对象标识的字段确定为最终,这样就没有机会篡改该标识。然后,您的add()方法应该是:
public Mass add(Mass rhs){
return new Mass(this.mass + rhs.mass);
}
public static Mass add(Mass lhs, Mass rhs){
return new Mass(lhs.mass + rhs.mass);
}这两种方法所做的事情是完全相同的,因此其中一种方法是多余的。我们Java程序员更习惯于非静态风格,所以我会消除静态方法。
还有一件事:我建议实现一个toString()方法,这样Mass实例就不会显示为“Mass@123abc 456”,而是有一个可读的表示形式,比如"25 kg“。并让您的IDE基于字段equals()创建hashCode()和mass实现。
https://codereview.stackexchange.com/questions/201618
复制相似问题