創建子類時父類構造方法中調用其他被子類覆蓋的方法
筆試遇到一個這樣的題:
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