Javainheritance – 请解释一下
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类inheritance自A类 ,即公共成员,无法查看/inheritance私有函数。 所以在B组中 ,我们可以调用talk() 。 //因为它是由父类inheritance的。
现在,在talk()方法中,调用sayIt(),因为sayIt()是在B类中定义的,
我希望在执行this.sayIt()时调用B.sayIt() 。
“这个”不是指B级吗?
请解释。
因为您将sayIt()定义为私有,所以B类不能覆盖它。 因此,您有两个sayIt()定义,而不仅仅是一个被子类覆盖的定义。
在A类代码的一部分内部,即使B类版本受到保护或公开,它也始终从A类调用该版本。 这是因为A类只知道A类中的版本,因为B类版本不是覆盖,而是一种完全不同的方法,恰好可以共享相同的名称。
在B类代码的一部分内部,它总是从类B调用该版本,因为A类版本被标记为私有。 正如其他人所指出的,如果您将定义更改为受保护或公开,它将对B类可见,并且它将执行您想要的操作。
请注意,如果您要使用默认(包)可见性,那么范围规则将变得非常复杂,实际结果将根据哪个子类在同一个包中以及哪些子类在不同的包中而有所不同。
考虑在sayIt
上sayIt
protected
而不是private
。 sayIt
在B上并没有压倒在A.上
您正在尝试覆盖私有方法。 没有任何意义。
如果您更改要保护的“sayIt”方法,它将像您期望的那样工作。
看起来你对如何使用重写方法感到有点困惑。 如果我没有弄错的话,你要做的就是在C ++中完全没问题,但在Java中却没有。
是的, b.talkIt()
“this”是指B类,但由于sayIt()
在A中是私有的,而talkIt()
在A中是talkIt()
而在B中未被覆盖,因此sayIt()
将被引用到A中的一个。
你可以这样看待它。 sayIt()
的A是私有的,所以它不能被覆盖。 由于它没有被覆盖, sayIt()
通过A的方法调用sayIt()
将始终指向A已知的那个(因为它没有被覆盖)。
希望这可以帮助。
“不是”这个“是指B级?” – 不。虽然您从B类创建了一个实例,但仍然引用了基本类型的方法,即talk()。 实现同一目标的一种方法是通过模板方法模式。
/ BB
因为sayIt是一个私有方法,所以它实际上没有被覆盖。 帮助理解这一点的一种方法是将@Override注释添加到您认为覆盖超类中的内容的任何方法。 如果你错了(在这种情况下),那么编译器会告诉你。
因为在talk
你对this.sayIt
和对象B是A的实例。
对象A不知道B中的方法。使用sayIt
抽象方法将对象A作为一个抽象类,您可以在A talk中调用或更改sayIt
可见性。
此外 – 使用注释,IDE将通知您警告。
根据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没有inheritanceA.sayIt(),因此没有覆盖它。
稍微偏离主题但可以帮助您更好地理解Javainheritance。
http://webmoli.com/2008/08/02/why-multiple-inheritance-is-not-allowed-in-java/