首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >用java表示质量的度量类的单位

用java表示质量的度量类的单位
EN

Code Review用户
提问于 2018-08-13 21:50:13
回答 2查看 1K关注 0票数 1

我正在查看这个答案,以便在java中处理单元。这个概念对我来说很有趣,只是我不喜欢它必须是每个有质量的对象,而不是单独封装一个Mass类,这样就不需要重复这种模式了。这就是我想出来的。

代码语言:javascript
复制
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);
    }

}

除了对这些问题的回答之外,还需要寻求任何批评:

  • 我在用java做类运算,对吗?它没有重载操作符,所以我不确定算术的约定是什么。
  • 对于函数和变量的单位部分,我没有使用下骆驼情况,尽管下骆驼情况是惯例,但我觉得很难看到toKg或toKG,尤其是在理论上可以用在不同的单位时,Nm和nm是两种不同的东西。
  • 是否有更好的方法来管理转换函数,似乎每次添加一个新的单元时我都要添加两个?对于10辆可转换的单位,如公斤和克,那又如何呢?有没有一种我可以在那里使用的特殊模式(如公斤、克、镁等)?
EN

回答 2

Code Review用户

发布于 2018-08-14 02:55:37

对于Mass,我会定义一些常量。

代码语言:javascript
复制
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”)单元定义您的转换。

代码语言:javascript
复制
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成为一个常量值类。

代码语言:javascript
复制
private final double mass;

public Mass(double kg) {
    mass =  kg;
}

public Mass(double quantity, Mass unit) {
    mass = quantity * unit.mass;
}

新单位只意味着定义新的类常量。

代码语言:javascript
复制
Mass weight = new Mass( 100, Mass.kg );
double pounds = weight.in( Mass.lb );
double ounces = weight.in( Mass.oz );

如注释中所述,如果跟踪quantity类中每个单元维度的大小,则可以将其扩展为完整的单位计算器。

票数 2
EN

Code Review用户

发布于 2018-08-18 19:59:39

除了AJNeufeld的回答:

您有两个add()方法。

代码语言:javascript
复制
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的下列代码行:

代码语言:javascript
复制
Mass mass10kg = Mass.from_kg(10.0);
mass10kg.add(Mass.from_kg(15.0));

第二行修改以前表示10公斤的质量实例,现在表示25公斤。还是一样的质量吗?当然不是,所以我建议不要那样做。

对于Java实例,最好将定义对象标识的字段确定为最终,这样就没有机会篡改该标识。然后,您的add()方法应该是:

代码语言:javascript
复制
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实现。

票数 1
EN
页面原文内容由Code Review提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://codereview.stackexchange.com/questions/201618

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档