天天看點

了解 Java 構造函數不可以繼承

在讀Java的文檔的時候  http://docs.oracle.com/javase/tutorial/java/IandI/subclasses.html

這裡有一句是講,Constructors 不是成員函數,是以它不可以被繼承。但是他可以被調用。

“A subclass inherits all the members (fields, methods, and nested classes) from its superclass. Constructors are not members, so they are not inherited by subclasses, but the constructor of the superclass can be invoked from the subclass.”

我們怎樣了解這個問題呢?

Constructors 是在一個類建立的時候,使用者建立類執行個體的時候被調用的特殊函數。它不是一個類的成員函數,它隻能代表這個類本身。

不可以建立一個繼承的子類時,用父類的構造方法建立子類。

public class main {
	public static void main (String[] arg){
		Son s = new Son ();  // code 1
	}
}

class Father{
	public Father (){
		System.out.println("Father Construtor");
	}
	
	public Father (int x){
		System.out.println("Father Construtor " + x);
	}
	
	public void Father (){
		System.out.println("Father member function");
	}
}

class Son extends Father { 
	public Son (){
		super(1);
		System.out.println("Son Construtor");
	}
	
	public void Father(){
		System.out.println("Inherited Father member function.");
		super.Father();
	}
}
           

例如:上面一個繼承關系的類。對于code 1處。

我們如果在建立子類的時候,使用父類的構造方法,我們需要寫成這樣。

Son s = new Father ();

這時候,編譯器會報“Type mismatch: cannot convert from Father to Son” 錯誤。

如果我們進行強制轉換,如下:

Son s = (Son)new Father ();

這時候,編譯器無法發現有什麼錯誤,但是運作的時候會抛出下面異常。

Exception in thread "main" java.lang.ClassCastException: Father cannot be cast to Son at main.main(main.java:4)

父類無法轉換成子類。其本質上,建立的仍是一個父類。

如果在Son類中,增加父類constructor的函數。

public Father (){
	
}
           

去嘗試重載父類constructor,編譯器會報錯。 

是以,編譯器如果要構造一個類,必須要有和類名字相同的構造函數才可以。

也就是說,構造函數是用來造唯一的東西的。不能用一個構造函數即造爸爸,又造兒子。這樣身份就亂了。

下面的代碼是合法的代碼,從下面的代碼可以看出來,構造函數不是一個成員函數。

class Father{
	public Father (){
		System.out.println("Father Construtor");
	}
	
	public Father (int x){
		System.out.println("Father Construtor " + x);
	}
	
	public void Father (){
		System.out.println("Father member function");
	}
}
           

編譯器不會對上面的代碼報成員函數沖突錯誤。因為Constructor不是一個成員函數。

如果我們在類中再增加下面一個函數,編譯器會報 Duplicate method Father() in type Father 錯誤,原因是兩個成員函數發生了沖突。

public int Father (){
		System.out.println("Father member function");
           
<span style="white-space:pre">		</span>return 1;
	}