android端父类调用子类重写的方法

看一段代码:

public class main_class {
    public static void main(String[] args){
        new c2();
    }
}
class c1{
    String name="aaaaaa";
    //父类构造函数
    public c1(){
        print();
    }
//该构造函数自始至终就没有被调用过
    public void print(){
        System.out.println(name);
    }
}

class c2 extends c1{
    String name="asdg";
//构造函数:
    public c2(){
        System.out.println(name);
    }

//重写父类中的print()函数
    public void print(){
        System.out.println(name);
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
输出:
null
asdg
  • 1
  • 2
  • 3

分析:

1.初始化c2()时,先初始化c2的父类:c1()
初始化c1()的静态变量和静态代码块
初始化c2()的静态变量和静态代码块
2.初始化c1()的非静态变量,初始化父类的构造函数。
  如果父类的构造函数中调用的方法被子类重写,那么调用的会是子类的方法。

3.初始化c2()的非静态变量,初始化子类的构造函数。

new c2();在创造派生类的过程中首先创建基类对象,然后才能创建派生类。
创建基类即默认调用c1()方法,在方法中调用print()方法,由于派生类中存在此方法,则被调用的print()方法是派生类中的方法,此时派生类还未构造,所以变量name的值为null


先成员变量再构造方法,先父类再子类
多态表现:有同名方法执行子类的

执行 c1 b = new c2();时,由于多态 b编译时表现为c1类特性,运行时表现为c2类特性
c1 b = new c2();不管是哪种状态都会调用c1构造器执行 print()方法;
执行方法时,由于多态表现为子类特性,所以会先在子类是否有 print();
而此时子类尚未初始化(执行完父类构造器后才会开始执行子类), 如果有 就 执行(此时, 因为还没有调用子类构造函数, 所以子类的 name输出为 null),没有再去父类寻找。

猜你喜欢

转载自blog.csdn.net/qq_35893839/article/details/80852070