Java继承中的方法重写

use*_*125 7 java inheritance

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所以不能覆盖它.

这意味着当你定义一个pripac方法时Concrete1,它们只是碰巧与方法同名的方法Base,而不是覆盖.另外两种方法pro,并pub保护公众分别,所以是可见的Concrete1.因此,这些propub方法Concrete1是对同名方法的重写Base.

因为show已定义Base,所以编译调用了4中定义的方法Base.执行时,JVM会查看是否有任何被覆盖以及是否执行了重写的方法.如上所解释的,pri并且pac没有被重载所以Base版本被执行,其中作为propub如此的Concrete1版本被执行.

如果你要将show方法移动到Concrete1而不是Base那时它将执行定义的4个方法,Concrete1因为那些方法是可见的show.