java继承之private方法覆盖的问题解析



java继承之private方法覆盖的问题解析。一个类Derived extends Base时,子类把父类某个方法覆盖了,而且是private方法,会调到谁的?

先看一个例子:
package wzq.j2se;

class Base{
public void f(){
System.out.println(“Base.f”);
g();
h();
i();
j();
}
protected void g(){
System.out.println(“Base.g”);
}
private void h(){
System.out.println(“Base.h”);
}
void i(){
System.out.println(“Base.i”);
}
public void j(){
System.out.println(“Base.j”);
}
public void k(){
System.out.println(“Base.k”);
}
}
class Derived extends Base{
public void f(){
System.out.println(“Derived-f”);
super.f();
}
protected void g(){
System.out.println(“Derived-g”);
}
private void h(){
System.out.println(“Derived-h”);
}
public void i(){
System.out.println(“Derived-i”);
}
public void j(){
System.out.println(“Derived-j”);
}
}

public class Main{
public static void main(String[] args){
/*Base obj = new Derived();
obj.f();*/

/*Base obj1 = new Base();
obj1.f();*/

Base obj2 = new Derived();
obj2.f();
//obj2.h();
//obj2.i();
//obj2.k();
}
}
/**
调用obj2.f();输出:
Derived-f
Base.f
Derived-g
Base.h
Derived-i
Derived-j
*/
首先要说明一下,
Derived obj2 = new Derived();
obj2.f();

Base obj = new Derived();
obj.f();
效果是一样的,因为调谁的方法关键看这个对象是谁,很显然,new的是谁这个对象就是谁。
看一下调用流程:
首先调用的是子类的f(),
里面调用了父类的f(),
父类的f()里面又调用了
g();
h();
i();
j();
问题出来了,这里到底该调是子类的还是父类的?答案是,哪一个对象在调,就调的谁的!对象是子类,所以理论上讲,这几个都该调到子类的方法。
但由于
private void h()
这种被private修饰的方法,是不能被子类覆盖的。
private方法不能重写,即使子类中的方法名和父类的private方法一致,也只能看做是一个新的方法,而不是重写
当一个类被继承后,用子类对象去调用它的方法,如果方法被覆盖就会调用覆盖后的,否则调用父类的。
所以说,调用h和k效果是一样的,都可以看作是未被覆盖的方法。
注意,以上是三个类。
obj2.h();这样会报编译错误的,因为这是private方法。
obj2.i();调用的是被覆盖后的方法。
obj2.k();由于没有被覆盖,所以,不存在调覆盖前还是覆盖后的说法,都是调的父类。
下面,再看一个例子:
package wzq.j2se.extend;


class Parent {

public void publicMethod(){
System.out.println(“hello parent public method”);
privateMethod();
protectedMethod();
defaultMethod();
nooverMethod();
}
private void privateMethod(){
System.out.println(“hello parent private method”);
}
protected void protectedMethod(){
System.out.println(“hello parent protected method”);
}
void defaultMethod(){
System.out.println(“hello parent defaultMethod method”);
}
public void nooverMethod(){
System.out.println(“hello parent nooverMethod method”);
}
}

public class Child extends Parent{

public void publicMethod(){
System.out.println(“hello child public—method”);
super.publicMethod();
}
private void privateMethod(){
System.out.println(“hello child private—method”);
}
protected void protectedMethod(){
System.out.println(“hello child protected–method”);
}
void defaultMethod(){
System.out.println(“hello child defaultMethod–method”);
}

public static void main(String args[]){
Parent child = new Child();
child.publicMethod();
// child.privateMethod(); //若不注释该行代码,则会出现编译错误:“The method privateMethod() from the type Parent is not visible”
}
}
/**
* private方法不能重写,即使子类中的方法名和父类的private方法一致,也只能看做是一个新的方法,而不是重写
* 当一个类被继承后,用子类对象去调用它的方法,如果方法被覆盖就会调用覆盖后的,否则调用父类的。
* 所以说,调用privateMethod和nooverMethod效果是一样的,都可以看作是未被覆盖的方法。
*/