关键字“this”可以吗?在Java中的抽象类中使用?
我尝试使用下面的示例,它工作正常。
我希望它选择子类的值,因为不会为超类创建对象(因为它是抽象的)。但它仅获取超类的字段值。
请帮我理解这背后的概念是什么?
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 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
回答标题中的问题:是,
this
可以在抽象类中使用。抽象Animal
与Dog
一起创建。覆盖字段
您无法按照您尝试过的方式覆盖字段。字段“不是虚拟的”,就像方法一样。
来自 Java 快速参考:重载、重写、运行时类型和对象方向 - 重写方法
如果可以,该字段可能至少必须受到保护:-)
创建抽象类的对象
它实际上是实例化的。
abstract
关键字仅确保实例化时以子类的形式实例化。实例化Dog
时,您同时实例化了Animal
!因此,Animal
上下文中的this
引用将始终引用Dog
或Cat
或其他任何内容,但在所有情况下,它都指的是某种动物
。 :-)正如下面的示例所示,即使在抽象类中,
this
引用也有意义:Prints:
Update: The
this
引用引用的是超类中的对象与子类中的对象相同。您可以尝试添加
到动物类中,并
在
Dog.speak()
中执行。你会看到它打印出来的是 true。To answer the question in the title: Yes,
this
can be used in an abstract class. An abstractAnimal
is created at the same time as aDog
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
If you could, the field would probably have had to be at least protected :-)
Creation of objects of abstract classes
It is actually instantiated.
The
abstract
keyword only ensures that, when instantiated, it's instantiated in the form of a subclass. When instantiating aDog
, you're at the same time instantiating anAnimal
! Thethis
reference in the context of anAnimal
will thus always refer to aDog
or aCat
or whatever, but in all cases it refers to someAnimal
. :-)As the example below illustrates, the
this
reference makes sense even in an abstract class:Prints:
Update: The
this
reference refers to the same object in the super class as in the sub class.You could try to add
to the animal class, and do
in
Dog.speak()
. You would see that it prints true.类中声明的任何字段都是唯一的,即使它与基类中的字段同名(即只有方法可以被覆盖,但不能覆盖字段)。因此,派生类中有两个不同的字段:
SuperAbstract.a
和SubClass.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
andSubClass.a
. The fact that the base class isabstract
has no impact.The
abstract
keyword simply signifies that a class cannot be instantiated, i.e. you cannot writenew SuperAbstract()
. You can only instantiate object of the subclass, which must override all methods markedabstract
.您提供的代码包含变量
a
作为SuperAbstract
类的私有成员。因为,您似乎没有重写该函数,它代表了 SuperAbstract 类中的代码,执行它将可以访问类本身中声明的 a ,无论它是从任何继承的类调用的事实。要访问后面变量的值,您需要通过在派生类中再次定义该函数来重写该函数。最终的代码如下所示:在上面的代码中,我将
a
更改为 protected,以便也可以从派生类访问它。The code you provided contains variable
a
as private member of theSuperAbstract
class. Since, you don't seem to override the function, it represents the code from theSuperAbstract
class, and executing it will get access to thea
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:In the above code I changed the
a
to protected, so that it could be accessed from the derived class too.