关键字“this”可以在Java的抽象类中使用吗?

2022-09-01 20:32:19

我用下面的示例尝试,它工作正常。

我希望它选择子类的值,因为不会为超类创建对象(因为它是抽象的)。但它只是拾取超级类的字段值。

请帮助我了解这背后的概念是什么?

abstract class SuperAbstract {
    private int a = 2;
    public void funA() {
        System.out.println("In SuperAbstract: this.a " + a);
    }
}

class SubClass extends SuperAbstract {
    private int a = 34;
}

我打电话new SubClass.funA();

我期望它打印34,但它正在打印2。

P.S.:我想知道的是,为什么在抽象类中使用它不会给我一个错误?

如下文所强调的,它将在实例上工作,抽象类将没有实例。this

在实例方法或构造函数中,这是对当前对象的引用 , 该对象是正在调用其方法或构造函数的对象。可以使用 this 从实例方法或构造函数中引用当前对象的任何成员。从: http://java.sun.com/docs/books/tutorial/java/javaOO/thiskey.html


答案 1

回答标题中的问题:是的,可以在抽象类中使用。抽象是在创建的同时创建的。thisAnimalDog

覆盖字段

您无法以您尝试过的方式覆盖字段。字段“不像方法那样是虚拟的”。

来自 Java 快速参考:重载、重写、运行时类型和面向对象 - 重写方法

  • 字段不能被覆盖,但它们可以被隐藏,即如果您在子类中声明与超类中字段同名的字段,则只能使用super或超类类型访问超类字段

如果可以的话,这个领域可能至少必须受到保护:-)

创建抽象类的对象

因为不会为超类创建对象(因为它是抽象的)

它实际上是实例化的。

关键字仅确保在实例化时,它以子类的形式实例化。在实例化 a 时,您同时实例化了 !因此,在遗嘱的上下文中引用总是指a或a或其他任何东西,但在所有情况下,它都是指一些.:-)abstractDogAnimalthisAnimalDogCatAnimal

如下面的示例所示,即使在抽象类中,引用也是有意义的:this

abstract class Animal {
    public String name;

    public Animal(String name) {
        System.out.println("Constructing an Animal");
        this.name = name;
    }

    public abstract void speak();
}

class Dog extends Animal {
    public Dog(String name) {
        super(name);
        System.out.println("  Constructing a Dog");
    }
    public void speak() {
        System.out.println("Bark! My name is " + name);
    }
}

public class Test {
    public static void main(String... args) {
        new Dog("Woffy").speak();
    }
}

指纹:

Constructing an Animal
  Constructing a Dog
Bark! My name is Woffy

更新:引用引用超类中与子类中的对象相同的对象。this

您可以尝试添加

public Animal getSuperThis() { return this; }

到动物类,并做

System.out.println(this == getSuperThis());

在。你会看到它打印真实。Dog.speak()


答案 2

类中声明的任何字段都是唯一的,即使它与基类中的字段具有相同的名称(即,只能重写方法,但不能重写字段)。因此,派生类中有两个不同的字段:和 。基类是的事实没有影响。SuperAbstract.aSubClass.aabstract

关键字仅表示类无法实例化,即您无法编写 。您只能实例化子类的对象,该子类必须覆盖所有标记为 的方法。abstractnew SuperAbstract()abstract


推荐