在Java中使用use和this关键字的正确方法是什么?

时间:2018-10-17 04:54:43

标签: java

因此,我正在扩展Java Rectangle类。我碰巧对thissuper的使用以及何时应使用它们感到困惑。我知道super是超类(父类),而this是您从中调用它的当前类。

我目前有一个从BetterRectangle类扩展的Rectangle类和一个方法:

boolean isCongruent(Rectangle r)
{
    if(r.width == super.width && r.height == super.height)
    {
        return true;
    }
    return false;
}

如果我使用this.widththis.height而不是super是否重要? 不管两者给我相同的答案,哪种方法更正确?

4 个答案:

答案 0 :(得分:1)

如果您的子类具有字段width(和height),那么根据初始化字段的方式,super.width的值可以与this.width不同。这是一个快速测试:-

import java.awt.*;

public class BetterRectangle extends Rectangle {

    public int width;

    void testWidth() {
        System.out.println("width = " + width);
        System.out.println("this.width = " + this.width);
        System.out.println("super.width = " + super.width);
    }
}

-

public static void main(String[] args) {
    Rectangle rect = new BetterRectangle();
    rect.width = 10; //sets the value of super class's field
    ((BetterRectangle) rect).width = 90; //sets the value of subclass's field

    ((BetterRectangle) rect).testWidth();
}

此打印:-

width = 90
this.width = 90
super.width = 10

请注意,由于数据隐藏widththis.width会打印相同的内容。您必须添加super关键字才能访问超类的字段。

如果子类中没有width变量,那么super.widththis.width指向同一个字段,那么为什么不只使用width? / p>

希望这会有所帮助。

答案 1 :(得分:1)

通常,几乎不需要真正使用这两种方法。或超级。

看看您的iscongruent()方法,问问自己它怎么可能返回false。答案:只有当超类和子类都具有相同名称的成员时才有可能,也就是说,有多个名为“ width”和/或“ height”的distinc字段。这是不好的做法。

为什么会这样?假设这些字段具有相同的语义。在任何时候。那么,为什么该领域有两种不同的表象?这是简单的冗余,并且是错误的来源。消除两者之一,就可以解决问题。相反地​​,假设这些字段可能带有不同的语义。您可能希望至少通过getter(也许还有setter)在子类中公开那些语义。因此,现在您的上级和子类中都具有具有 相同 签名但具有 差异 的吸气剂(甚至是二传手)语义。那是简单的反合同设计。子类绝不能改变其父类建立的方法的语义。最后,如果您不想在子类中公开同名字段,则没有什么可以阻止您将其命名为'localWidth'或'subWidth'或任何其他由 提供的名称更好,更详细地解释了预期的语义

也就是说,在某些情况下,使用“ this”和/或“ super”是必要的,甚至是不可避免的:

在构造函数中,当从已与字段具有相同名称的参数值设置字段时:

this.x = x;  /* x = x would mean an assignment to the method parameter, not the field */

在替代实现中,当您还需要执行超类中定义的代码时:

method ( ... ) {
  super.method( ... );
  /* some extra code here to deal with the extra state in the sub class */
}

可能还有更多,但总的来说,广泛使用“ this”和“ super”会导致过多的“噪音”,因此可以避免在不影响可读性的情况下避免使用 。当然,这只是见解和偏爱的样式。

答案 2 :(得分:0)

  

如果我使用this.width和this.height而不是super会不会很重要?

如果您的子类继承自其父类的属性(在本例中为Rectangle的widthheight),则您的子类现在拥有widthheight作为其子类自己的属性。

因此,如果您打算访问子类的属性,则使用this(指的是类本身)会更有意义吗?因此,我将继续使用this

继承给子级的属性

class Parent{  
    protected int width = 5;
    protected int height = 5;
}

class Child extends Parent{

    public Child(int width, int height){
        this.width = width;
        this.height = height; 
    }

    public int getHeight() {
        return this.height;
    }

    public int getWidth() {
        return this.width;
    }

    public int getSuperHeight() {
        return super.height;
    }

    public int getSuperWidth() {
        return super.width;
    } 
}

测试运行

Child c = new Child(2, 3);
System.out.println(c.getWidth() + " " + c.getHeight());             //2 3
System.out.println(c.getSuperWidth() + " " + c.getSuperHeight());   //2 3

就像ScarryWombat提到的那样,如果属性被子类中声明的属性掩盖,则使用thissuper会有所不同。 this现在引用子类中声明的属性,而不是继承的属性。

继承给子级但被屏蔽的属性

class Child extends Parent{

    private int width;
    private int height;

    public Child(int width, int height){
        this.width = width;
        this.height = height; 
    }

    public int getHeight() {
        return this.height;
    }

    public int getWidth() {
        return this.width;
    }

    public int getSuperHeight() {
        return super.height;
    }

    public int getSuperWidth() {
        return super.width;
    }    
}

测试运行

Child c = new Child(2, 3);
System.out.println(c.getWidth() + " " + c.getHeight());             //2 3
System.out.println(c.getSuperWidth() + " " + c.getSuperHeight());   //5 5

答案 3 :(得分:-1)

最好的方法可能是查看标准Java类如何访问变量。 javax.swing.text.DefaultCaret扩展了Rectangle。除非存在局部变量冲突-否则变量访问不使用任何thissuper指定符。我会坚持:)。

例如,这是repaint方法:

protected final synchronized void repaint() {
    if (component != null) {
        component.repaint(x, y, width, height);
    }
}