package P1;
public class Base {
private void pri( ) { System.out.println("Base.pri()"); }
void pac( ) { System.out.println("Base.pac()"); }
protected void pro( ) { System.out.println("Base.pro()"); }
public void pub( ) { System.out.println("Base.pub()"); }
public final void show( ) {
pri();
pac();
pro();
pub();
}
}
Run Code Online (Sandbox Code Playgroud)
和
package P2;
import P1.Base;
public class Concrete1 extends Base {
public void pri( ) { System.out.println("Concrete1.pri()"); }
public void pac( ) { System.out.println("Concrete1.pac()"); }
public void pro( ) { System.out.println("Concrete1.pro()"); }
public void pub( ) { System.out.println("Concrete1.pub()"); }
}
Run Code Online (Sandbox Code Playgroud)
我正在执行
Concrete1 c1 = new Concrete1();
c1.show( );
Run Code Online (Sandbox Code Playgroud)
现在,输出显示为
Base.pri()
Base.pac()
Concrete1.pro()
Concrete1.pub()
有人可以解释为什么会这样吗?根据我对继承的理解,这应该发生了:
1)P2.concrete1继承P1.Base
2)创建具体1的c1对象
3)c1.show()被调用.由于P1.Base.show()是public,它可以被调用.
4)现在,在继承之后的P2.concrete1中,只有它自己的方法(pri,pac,pro,pub)和P1.Base的可继承方法(pro,pub,show)是可访问的.
现在为什么它们甚至无法访问时会在输出中显示Base.pri()和Base.pac()?
很明显,我对继承没有非常明确的基本理解.有人可以解释这种情况以及继承实际上是如何"结构化"的.我曾经认为超类的可继承方法和字段会叠加到子类上.但这种推理显然是错误的.
谢谢!
EdC*_*EdC 12
简短的回答是,您只能覆盖可见的方法.前两种方法,pri并且pac是私人和包装保护的分别.因为类外没有任何东西可以看到私有方法,所以它不能被覆盖.同样因为Concrete1它在不同的包中Base也看不到Base.pac所以不能覆盖它.
这意味着当你定义一个pri和pac方法时Concrete1,它们只是碰巧与方法同名的方法Base,而不是覆盖.另外两种方法pro,并pub在保护和公众分别,所以是可见的Concrete1.因此,这些pro和pub方法Concrete1是对同名方法的重写Base.
因为show已定义Base,所以编译调用了4中定义的方法Base.执行时,JVM会查看是否有任何被覆盖以及是否执行了重写的方法.如上所解释的,pri并且pac没有被重载所以Base版本被执行,其中作为pro和pub如此的Concrete1版本被执行.
如果你要将show方法移动到Concrete1而不是Base那时它将执行定义的4个方法,Concrete1因为那些方法是可见的show.