Java子父類中的建構函式例項化過程
阿新 • • 發佈:2018-12-26
其實我們發現子類繼承父類操作很簡單,如果要是去深入的研究下會發現,例項化過程並非是我們看到的那樣,我們就以程式碼舉例來說明;
問大家,以下程式碼執行會輸出什麼呢?
package com.oop;
/**
* 定義動物物件
* @author Liudeli
*
*/
class Animal {
public Animal() {
System.out.println("Animal()--建構函式");
}
}
/**
* 定義狗物件
* @author Liudeli
*
*/
class Dog extends Animal{
}
/**
* 子父類中的建構函式例項化過程
* @author Liudeli
*
*/
public class Demo1 {
public static void main(String[] args) {
Dog d = new Dog();
}
}
沒有去深究這個問題,大部分會回答,不輸出任何,因為Dog類沒有任何構造方法,如果這樣想的其實就錯了,它一定會輸出父類無參構造方法的內容:
這是為什麼呢?
答:其實只要我們隨便建立一個類,就會有隱式的程式碼重點內容執行
會在子類的構造方法中執行 super(); 呼叫
/**
* 定義狗物件
* @author Liudeli
*
*/
class Dog extends Animal{
// 其實只要我們隨便建立一個類,就會有隱式的程式碼執行,只是我們看不到而已
Dog() {
super();
return;
}
}
子類有一個有參構造方法,new 子類(true),呼叫子類的有參構造方法,父類的無參構造方法一定會執行,因為在子類的任何構造方法中,都會預設呼叫 super();
package com.oop;
/**
* 定義動物物件
* @author Liudeli
*
*/
class Animal2 {
public Animal2() {
System.out.println("Animal()--建構函式");
}
public Animal2(boolean is) {
System.out.println("Animal2(boolean is)--建構函式 is:" + is);
}
}
/**
* 定義狗物件
* @author Liudeli
*
*/
class Dog2 extends Animal{
public Dog2() {
}
public Dog2(boolean is) {
System.out.println("Dog2(boolean is)--建構函式 is:" + is);
}
}
/**
* 子父類中的建構函式例項化過程
* @author Liudeli
*
*/
public class Demo2 {
public static void main(String[] args) {
// 我呼叫的是,子類的有參構造方法,父類的無參構造方法會執行
// 因為在子類的任何構造方法中,都會執行super();
Dog2 dog = new Dog2(true);
}
}
執行結果:
我們看不到的細節:
package com.oop;
/**
* 定義動物物件
* @author Liudeli
*
*/
class Animal3 {
public Animal3() {
System.out.println("Animal()--建構函式");
}
public Animal3(boolean is) {
System.out.println("Animal(boolean is)--建構函式 is:" + is);
}
}
/**
* 定義狗物件
* @author Liudeli
*
*/
class Dog3 extends Animal{
public Dog3() {
// super(); 預設就有,只是我們看不到而已,super()它在子類任何建構函式中的第一行
super(false); // 這樣寫報錯,為什麼會報錯因為在子類的任何建構函式中都會執行 super()
// 你如果寫了 super(引數); 就是不認它呼叫父類的super(), 所以它會報錯
}
public Dog3(boolean is) {
// super(); 預設就有,只是我們看不到而已,super()它在子類任何建構函式中的第一行
super(false); // 這樣寫報錯,為什麼會報錯因為在子類的任何建構函式中都會執行 super()
// 你如果寫了 super(引數); 就是不認它呼叫父類的super(), 所以它會報錯
System.out.println("Dog(boolean is)--建構函式 is:" + is);
}
}
/**
* 子父類中的建構函式例項化過程
* @author Liudeli
*
*/
public class Demo3 {
/*
* Demo3 的例項化必須執行以下程式碼,只是隱式的看不到而已
*/
// 主要 修飾符 public 是由於類開始定義的是public,所以它才是public,修飾符根據類的定義變化而變化
public Demo3() {
super();
return;
}
public static void main(String[] args) {
Dog3 dog = new Dog3(true);
}
}
在這裡有一個思考點,建立一個類不繼承任何類,預設無參建構函式必須執行 super(); ,那super呼叫了那個父類的無參建構函式?
答:最終超類 Object。
所以我們這樣寫,沒有任何問題,extends Object
package com.oop;
// 系統預設或直接間接的讓Object成為了父類,extends Object,只是我們看不到而已
public class Demo4 extends Object {
/*
* Demo3 的例項化必須執行以下程式碼,只是隱式的看不到而已
*/
// 主要 修飾符 public 是由於類開始定義的是public,所以它才是public,修飾符根據類的定義變化而變化
public Demo4() {
super();
return;
}
public static void main(String[] args) {
System.out.println("Demo4()...");
}
}
執行結果:
父類寫了一個有參構造方法,子類繼承父類,子類必須要寫一個和父類一樣引數的構造方法,因為父類寫了一個有參構造方法,父類的無參構造方法就沒有了,子類的無參構造方法就呼叫不到父類的無參構造方法了,需要讓子類的有參構造方法去super()呼叫;
public class Observer {
private String name;
private Secretary secretary;
public Observer(String name, Secretary secretary) {
this.name = name;
this.secretary = secretary;
}
}
public class StockObserver extends Observer{
// 子類必須要寫一個和父類同參的構造方法
public StockObserver(String name, Secretary secretary) {
super(name, secretary);
// TODO Auto-generated constructor stub
}
}