创建子类时父类构造方法中调用其他被子类覆盖的方法
笔试遇到一个这样的题:
public class Parent {
private static String city = "东莞";
public Parent ()
{
this.print();
}
public void print (){
printCity();
}
private static void printCity (){
System.out.println("parent:"+city);
}
static class Child extends Parent{
private static String city ="深圳";
public Child ()
{
//super.print();
}
public void print (){
printCity();
}
public static void printCity (){
System.out.println("Child:"+city);
}
}
public static void main(String[] args) {
Parent p = new Child();
}
}
//输出结果:Child:深圳
通过调试找到了调用的顺序:
new的时候会调用loadClass类加载器,调用父类无参构造器,父类无参构造器中调用了其他方法print(),在此过程中执行的对象都是子类对象,且子类中有print()函数,所以此处调用的print()为子类的print()方法。所以输出的是Child:深圳。
在删去子类的print()方法后,由于子类没有print()方法,所以调用父类的print()方法,输出:parent:东莞。
package inherited;
public class Parent {
private static String city = "东莞";
public Parent ()
{
this.print();
}
public void print (){
printCity();
}
public static void printCity (){
System.out.println("parent:"+city);
}
static class Child extends Parent{
private static String city ="深圳";
public Child ()
{
//super.print();
}
// public void print (){
// printCity();
// }
public static void printCity (){
System.out.println("Child:"+city);
}
}
public static void main(String[] args) {
Parent p = new Child();
}
}
//输出:
parent:东莞
在网上又找到了一串这样的代码
class Supper {
int i = 10;
public Supper() {
//System.out.println("111111");
print();
i = 20;
}
int j;
public void print() {
System.out.println("Supper==="+i);
}
}
class Sub extends Supper {
public Sub() {
//System.out.println("222222");
print();
super.print();
i = 40;
}
int i = 30;
public void print() {
System.out.println("Sub==="+i);
}
}
public class Test {
public static void main(String[] args) {
new Sub();
}
}
/*
输出:
Sub===0
Sub===30
Supper===20
*/
第一个输出Sub为0,是因为调用的父类构造器中的print(),调用的是子类的print()方法,此时子类还没有初始化 i ,所以 i 的值为0。第二次调用print()是子类构造器中的print(),此时 i 已被赋值,所以输出 i 为30。
new时,先调用类加载器——初始化父类的成员变量——调用父类构造器——构造器中调用了子类的print()(此时子类中的成员变量还没初始化,为默认值 0 )——父类构造器结束——初始化子类成员变量——调用子类构造器——子类构造器中调用了print()——输出 i 为初始化的30