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()时调用 B.sayIt()。
“this”不是指 B类?
请解释。
答案 0 :(得分:6)
因为你将sayIt()定义为私有,所以B类不能覆盖它。因此,你有两个sayIt()的定义,而不只是一个被子类覆盖的定义。
在A类代码的一部分内部,它总是会调用A类的版本,即使B类版本受到保护或公开。这是因为A类只知道A类中的版本,因为B类版本不是覆盖,但这是一种完全不同的方法,恰好可以共享相同的名称。
在B类代码的一部分内部,它总是会调用B类的版本,因为A类版本被标记为私有。正如其他人所指出的,如果您将定义更改为受保护或公开,那么它将对B类可见,它将按您的要求执行。
请注意,如果您要使用默认(包)可见性,那么范围规则将变得非常复杂,实际结果将根据哪个子类在同一个包中以及哪些子类在不同的包中而变化。
答案 1 :(得分:3)
考虑在protected
上制作private
而不是sayIt
。 B上的sayIt
未覆盖A上的sayIt
。
答案 2 :(得分:2)
您正在尝试覆盖私有方法。没有道理。
答案 3 :(得分:0)
如果您更改要保护的“sayIt”方法,它将按照您的预期工作。
对于如何使用重写方法,您似乎有点困惑。 如果我没有弄错的话,你在C ++中尝试做的事情是完全正确的,但在Java中则不然。
答案 4 :(得分:0)
是b.talkIt()
的“this”引用了B类,但由于sayIt()
在A中是私有的,而talkIt()
在A中是十分的,而在B中未被覆盖,{{1}将被引用到A中的那个。
你可以这样看待它。 A的sayIt()
是私有的,因此无法覆盖。由于它没有被覆盖,因此通过A的方法调用sayIt()
将始终指向A已知的那个(因为它没有被覆盖)。
希望这有帮助。
答案 5 :(得分:0)
“不”这“指的是B级?” - 不。虽然您从B类创建了一个实例,但仍然引用了基本类型的方法,即talk()。实现同一目标的一种方法是通过模板方法模式。
/ BB
答案 6 :(得分:0)
因为sayIt是一个私有方法,所以它实际上没有被覆盖。帮助理解这一点的一种方法是将@Override注释添加到您认为覆盖超类中的某些方法。如果你错了(如本例所示),那么编译器会告诉你。
答案 7 :(得分:0)
因为在talk
中您需要this.sayIt
而对象B是A的实例。
对象A不了解B中的方法。使对象A成为具有sayIt
抽象方法的抽象类,您可以在对话中调用或更改sayIt
的可见性。
另外 - 使用注释,IDE会通知您警告。
答案 8 :(得分:0)
根据Java语言规范8.4.8:
A class C inherits from its direct superclass and direct superinterfaces
all non-private methods (whether abstract or not) of the superclass and
superinterfaces that are public, protected or declared with default access
in the same package as C and are neither overridden nor hidden by a
declaration in the class.
所以B没有继承A.sayIt()因此没有覆盖它。
答案 9 :(得分:0)
稍微偏离主题,但可以帮助您更好地理解Java继承。
http://webmoli.com/2008/08/02/why-multiple-inheritance-is-not-allowed-in-java/