【问题标题】:When Should I use this in a method?我什么时候应该在方法中使用它?
【发布时间】:2017-09-04 20:09:55
【问题描述】:

我这里有这段代码,我正在尝试使用:

public class RationalNumber() {
    private int num;
    private int den;

    public RationalNumber(int n, int d) {
        num = n;
        den = d;
    }

    public void multiply(RationalNumber r) {
        /* missing code */
    }

    public int getNum() {
        return num;
    }

    public int getDen() {
        return den;
    }
}

在 public void multiply 方法中,我需要用方法 multiply 将 RationalNumber 的分子乘以 r 的分子,并将这个 RationalNumber 的分母乘以 r 的分母。下列哪一项可以用来替换 /* 缺失的代码 */ 使得 multiply().

我已将范围缩小到:

num = num * r.num;
den = den * r.den;

this.num = this.num * r.num;
this.den = this.den * r.den;

num = num * r.getNum();
den = den * r.getDen();

有人能告诉我其中哪一个(或多个)将使该方法按预期工作吗?

【问题讨论】:

  • 为什么不试试看呢?
  • 只是以第四/第五种方式夹起来:num *= r.num;num *= r.getNum();

标签: java class object methods this


【解决方案1】:

简而言之:这三个都应该有效,与最后一个变体只有一个区别:您的类不是最终类,它允许子类更改 getNum 和 getDen 的行为。

此外,将表示数字的类创建为可变的也很少见。也许最好把multiply的签名改成

public RationalNumber multiply(RationalNumber)

返回一个新的RationalNumber 与乘法的结果,而不是改变当前的内部状态。在这种情况下,实现将是

return new RationalNumber(num * r.num, den * r.num);

(或您提供的任何其他变体)

【讨论】:

    【解决方案2】:

    它们在功能上都是等效的。

    只有当您需要确保引用的是实例变量而不是局部变量或参数时,您才需要this。如果您的构造函数有名为numden 的参数,则需要编写

    this.num = num;
    this.den = den;
    

    指定要将参数num 分配给实例变量num

    但是,由于方法没有歧义,它们都可以工作。您还可以直接访问变量r.numr.den,因为即使它们是私有的,它们仍然可以被同一个 访问,而不仅仅是同一个实例。

    我会这样写

    num *= r.num;
    den *= r.den;
    

    【讨论】:

    • 它们在功能上并不完全等效:您可以覆盖子类中的 getter 以执行不同的操作:然后第三个将不同于第一个和第二个。如果您将课程定为决赛,它们将是相同的。
    【解决方案3】:

    这三种方式都是正确的,因为:

    1. num = num * r.num;
    2. den = den * r.den;
    

    第 1 行:将 num(实例变量)* r.num(r 的实例变量)结果分配给 num。即使 numden 具有私有访问权限,当您在其内部处理同一个类时,您也可以访问私有成员。

    第 2 行:将 den(实例变量)* r.den(r 的实例变量)结果分配给 den。

    this.num = this.num * r.num;
    this.den = this.den * r.den;
    

    在这段代码中,您使用 this 关键字明确表示 num 和 den 是类的实例变量。在这种情况下,没有必要,因为您没有阴影(当局部变量隐藏实例变量的名称时)。逻辑同上。

    num = num * r.getNum();
    den = den * r.getDen();
    

    您只是使用访问器方法 (get) 来获取私有字段的值。逻辑继续相同。因为,正如我已经说过的,当前对象可以访问同一类对象的私有成员,这将是不必要的。

    在这种情况下我会使用第一种方式;)

    【讨论】:

      【解决方案4】:

      我认为最后一个会按预期工作:

      num = num * r.getNum();
      den = den * r.getDen();
      

      【讨论】:

      • 其他人也一样。
      【解决方案5】:

      其实也有相反的意见:总是用this作为类的变量,确定这个变量属于谁。或者另一个:如果局部变量和类变量之间存在冲突,请使用一个。

      在我的工作中,我使用第二个:只有在必要时才使用this。代码中的单词越少,问题越少。

      因此,在您的示例中,您可以使用任何变体。

      【讨论】:

        【解决方案6】:

        试试这个,我觉得形式上最正确:

        this.num = this.num * r.getNum();
        this.den = this.den * r.getDen();
        

        【讨论】:

        • 它并不比其他任何一个更正确。如果您真的认为是,请解释原因。
        • 我会说,因为您在方法调用者传递的参数上调用 getter,而 this.numthis.den 澄清您正在为当前对象调用变量。注意我说的是形式..
        【解决方案7】:

        按照 Lothar 的回答,如果 multiply 方法返回一个全新的 RationalNumber 实例会更好。

        我什至会将方法设为类的静态方法,因为它只是RationalNumbers 之间的常见操作,而不是与修改它的类的单个实例交互的东西。

        这样,你可以这样称呼它:

        RationalNumber mul = RationalNumber.multiply(rn1,rn2);
        

        然后方法定义将是:

        public static RationalNumber multiply(RationalNumber rn1, RationalNumber rn2){
            return new RationalNumber(rn1.getNum() * rn2.getNum(), rn1.getDen() * rn2.getDen());
        }
        

        【讨论】:

        • 所以你也认为BigDecimal.multiply(BigDecimal multiplicand)应该是static?那只会使它使用起来更加麻烦,即你必须写BigDecimal.multiply(bd1, bd2),而不是bd1.multiply(bd2)
        • 这是一个很好的观点,虽然我不得不承认它使用起来不方便,但我觉得这样做可能有更大的原因,比如线程安全
        • 制作方法static如何提高线程安全性?使对象不可变,如Lothar suggested,就是这样做的。将其设为 static 并没有功能上的区别,只是使用起来很麻烦。
        • 也许我解释错了:我的意思是说您的 BigDecimal.multiply 示例将比我建议的静态方法提供更好的线程安全性
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2016-02-15
        • 2012-03-23
        • 2011-01-18
        • 2011-08-18
        • 2017-03-21
        • 2010-12-30
        相关资源
        最近更新 更多