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

发布于 2024-09-04 16:30:11 字数 808 浏览 5 评论 0原文

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

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

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

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。PS

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

如下文本强调 this 将在实例上工作,而抽象类不会有实例。

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

I tried with below example, it is working fine.

I expected it to pick sub-class's value since object won't be created for super class (as it is abstract). But it is picking up super class's field value only.

Please help me understand what is the concepts behind this?

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;
}

I am calling new SubClass.funA();

I am expecting it to print 34, but it is printing 2.

P.S.:
What I want to know is why using this in an abstract class not giving me an error?

As below text is emphasizing this would work on an instance and abstract classes won't have an instance.

Within an instance method or a
constructor, this is a reference to
the current object — the object whose
method or constructor is being called.
You can refer to any member of the
current object from within an instance
method or a constructor by using this.
from: http://java.sun.com/docs/books/tutorial/java/javaOO/thiskey.html

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

洛阳烟雨空心柳 2024-09-11 16:30:11

回答标题中的问题:this可以在抽象类中使用。抽象AnimalDog 一起创建。

覆盖字段

您无法按照您尝试过的方式覆盖字段。字段“不是虚拟的”,就像方法一样。

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

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

如果可以,该字段可能至少必须受到保护:-)

创建抽象类的对象

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

它实际上是实例化的。

abstract 关键字仅确保实例化时以子类的形式实例化。实例化 Dog 时,您同时实例化了 Animal!因此,Animal 上下文中的 this 引用将始终引用 DogCat 或其他任何内容,但在所有情况下,它都指的是某种动物。 :-)

正如下面的示例所示,即使在抽象类中,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();
    }
}

Prints:

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

Update: The this 引用引用的是超类中的对象与子类中的对象相同。

您可以尝试添加

public Animal getSuperThis() { return this; }

到动物类中,并

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

Dog.speak() 中执行。你会看到它打印出来的是 true。

To answer the question in the title: Yes, this can be used in an abstract class. An abstract Animal is created at the same time as a Dog is created.

Overriding fields

You can't override fields the way you have tried it. Fields "are not virtual" like methods.

From Java Quick Reference: Overloading, Overriding, Runtime Types and Object Orientation - Overriding Methods

  • fields cannot be overridden but they can be hidden ie if you declare a field in a subclass with the same name as one in the superclass, the superclass field can only be accessed using super or the superclasses type

If you could, the field would probably have had to be at least protected :-)

Creation of objects of abstract classes

since object won't be created for super class (as it is abstract)

It is actually instantiated.

The abstract keyword only ensures that, when instantiated, it's instantiated in the form of a subclass. When instantiating a Dog, you're at the same time instantiating an Animal! The this reference in the context of an Animal will thus always refer to a Dog or a Cat or whatever, but in all cases it refers to some Animal. :-)

As the example below illustrates, the this reference makes sense even in an abstract class:

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();
    }
}

Prints:

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

Update: The this reference refers to the same object in the super class as in the sub class.

You could try to add

public Animal getSuperThis() { return this; }

to the animal class, and do

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

in Dog.speak(). You would see that it prints true.

薄凉少年不暖心 2024-09-11 16:30:11

类中声明的任何字段都是唯一的,即使它与基类中的字段同名(即只有方法可以被覆盖,但不能覆盖字段)。因此,派生类中有两个不同的字段:SuperAbstract.aSubClass.a。基类是抽象的这一事实没有影响。

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

Any field declared in a class is unique, even if it has the same name as a a field in a base class (i.e. only methods can be overridden, but not fields). Therefore, there are two distinct fields in the derived class: SuperAbstract.a and SubClass.a. The fact that the base class is abstract has no impact.

The abstract keyword simply signifies that a class cannot be instantiated, i.e. you cannot write new SuperAbstract(). You can only instantiate object of the subclass, which must override all methods marked abstract.

╭ゆ眷念 2024-09-11 16:30:11

您提供的代码包含变量a 作为SuperAbstract 类的私有成员。因为,您似乎没有重写该函数,它代表了 SuperAbstract 类中的代码,执行它将可以访问类本身中声明的 a ,无论它是从任何继承的类调用的事实。要访问后面变量的值,您需要通过在派生类中再次定义该函数来重写该函数。最终的代码如下所示:

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

class SubClass extends SuperAbstract {
    private int a = 34;
    //Overriding the above function
    public void funA() {
        System.out.println("In SubClass: " + a);
        //Or even check using the super keyword
        System.out.println("In SubClass with super: " + super.a);
        //Now call the function to display the value of a from SuperAbstract
        super.funA();
    }
}

在上面的代码中,我将 a 更改为 protected,以便也可以从派生类访问它。

The code you provided contains variable a as private member of the SuperAbstract class. Since, you don't seem to override the function, it represents the code from the SuperAbstract class, and executing it will get access to the a declared in the class itself, regardless of the fact that it is being called from any inherited class. To access the value of the later variable, you need to override the function by defining the function again in the derived class. The final code looks like this:

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

class SubClass extends SuperAbstract {
    private int a = 34;
    //Overriding the above function
    public void funA() {
        System.out.println("In SubClass: " + a);
        //Or even check using the super keyword
        System.out.println("In SubClass with super: " + super.a);
        //Now call the function to display the value of a from SuperAbstract
        super.funA();
    }
}

In the above code I changed the a to protected, so that it could be accessed from the derived class too.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文