Java继承-请解释一下
class A {
public void talk(){
this.sayIt();
}
private void sayIt(){
System.out.println("class A says...");
}
}
class B extends A {
private void sayIt(){
System.out.println("class B says...");
}
}
测试类,主要方法:
B b = new B();
b.talk()
//output
class A says...
我无法得到这个,因为:
B 类 继承自A 类,公共成员,并且无法查看/继承私有函数。所以在B类中,我们可以调用talk()。 //因为它是由父类继承的。
现在,在talk()方法中,调用了sayIt(),因为sayIt() 是在 B 类 中定义的,
我希望当 this. sayIt() 被执行。
“this”不是指B 类吗?
请解释一下。
class A {
public void talk(){
this.sayIt();
}
private void sayIt(){
System.out.println("class A says...");
}
}
class B extends A {
private void sayIt(){
System.out.println("class B says...");
}
}
Test class, main method:
B b = new B();
b.talk()
//output
class A says...
I cannot get this since:
Class B inherits from class A, the public member and cannot see/inherit the private function. So in class B, we could call talk(). //since it is inherited by the parent class.
Now, in the talk() method, there is a call to sayIt() since sayIt() is defined in class B,
I would expect a call to B.sayIt() to be made when this.sayIt() is executed.
Doesn't "this" refer to the class B?
Please Explain.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(10)
因为您将 sayIt() 定义为私有,所以 B 类无法覆盖它。因此,您有两个 sayIt() 定义,而不仅仅是一个被子类覆盖的定义。
在 A 类代码的一部分内,它将始终调用 A 类的版本,即使 B 类版本是受保护的或公共的。这是因为类 A 只知道类 A 的版本,因为类 B 版本不是重写,而是完全不同的方法,而且恰好共享相同的名称。
在 B 类代码的一部分内,它将始终调用 B 类的版本,因为 A 类版本被标记为私有。正如其他人所指出的,如果您将定义更改为 protected 或 public,它将对 B 类可见,并且它将执行您想要的操作。
请注意,如果您要使用默认(包)可见性,则范围规则将变得非常复杂,并且实际结果将根据哪些子类位于同一包中以及哪些子类位于不同包中而有所不同。
Because you defined sayIt() to be private, class B cannot override it. As such, you have two definitions of sayIt() rather than just one that is overriden by a subclass.
While inside a section of class A code, it will always call the version from class A, even if the class B version was protected or public. This is because class A only knows about the version from class A since the class B version is not an override, but a completely different method that just so happens to share the same name.
While inside of a section of class B code, it will always call the version from class B since the class A version is marked private. As noted by others, if you change the definition to protected or public, it will be visible to class B and it will do what you want.
Note that if you were to use the default (package) visibility, the scoping rules would get to be very complex and the actual results would vary depending on which subclasses are in the same package and which are in different ones.
考虑在
sayIt
上设置protected
而不是private
。 B 上的sayIt
不会覆盖 A 上的sayIt
。Consider making
protected
instead ofprivate
onsayIt
.sayIt
on B is not overridingsayIt
on A.您正在尝试覆盖私有方法。它没有任何意义。
You are trying to override private methods. It has no sense.
如果您将“sayIt”方法更改为受保护,它将像您期望的那样工作。
您似乎对它如何与重写方法一起工作有点困惑。
如果我没记错的话,你想要做的事情在 C++ 中是完全可以的,但在 Java 中却不行。
If you change the "sayIt" method to be protected it will work like you expect it to.
It seems like you're a little bit confused about how it works with overriding methods.
If I'm not mistaken, what you are trying to do is perfectly alright in C++, but not in Java.
是的,
b.talkIt()
的“this”引用了 B 类,但由于sayIt()
在 A 中是私有的,而talkIt()
是在 A 中贴标并且在 B 中未覆盖,sayIt() 将引用 A 中的那个。您可以这样看。 A 的 sayIt() 是私有的,因此不能被覆盖。由于它没有被重写,A 的方法调用的 sayIt() 将始终指向 A 已知的方法(因为它没有被重写)。
希望这有帮助。
Yes "this" of
b.talkIt()
refer to the B class but sincesayIt()
is private in A andtalkIt()
is decalred in A and not overridden in B, thesayIt()
will be referred to the one in A.You can look at it this way.
sayIt()
of A is private so it cannot be overridden. Since it is not overridden,sayIt()
call by methods of A will always point to the one known to A (as it is not overridden).Hope this helps.
“这个不是指B级吗?” - 不。虽然您从类 B 创建了实例,但您仍然引用基本类型的方法 talk()。实现相同目标的一种方法是通过模板方法模式。
/BB
"Doesn't "this" refer to the B class ?" - No. Though you create a the instance from class B you still refer the method of the base type which is talk(). One way you can achieve this same objective is thru template-method pattern.
/BB
因为 say 是一个私有方法,所以它实际上并没有被重写。帮助理解这一点的一种方法是将 @Override 注释添加到您认为覆盖超类中的某些内容的任何方法中。如果你错了(如本例),编译器会告诉你。
Because sayIt is a private method, it is in fact not overridden. One way to help understand this is to add the @Override annotation to any method that you think overrides something from the superclass. If you are wrong (as in this case) then the compiler will tell you.
因为在
talk
中,您引用了this.sayIt
并且对象 B 是 A 的实例。对象 A 不知道 B 中的方法。使用
将对象 A 设为抽象类>sayIt
抽象方法,您在演讲中调用或更改sayIt
的可见性。另外 - 使用注释,IDE 会通过警告通知您。
Because in
talk
you reffer tothis.sayIt
and object B is instance of A.Object A has no knowledge of methods in B. Make object A an abstract class with
sayIt
abstract method which you call in A talk or change visibility ofsayIt
.Also - use annotaions and IDE will notify you with warnings.
根据Java语言规范8.4.8:
所以B没有继承A.sayIt(),因此没有重写它。
According to Java language specification 8.4.8:
So B did not inherit A.sayIt() and hence did not override it.
稍微偏离主题但可以帮助你更好地理解Java继承。
Slightly deviate from the topic but can help you to understand the Java inheritance better.