understanding constructors
--How constructors differ from methods
By Robert Nielsen, JavaWorld.com, 10/13/00
[譯] 馬嘉楠 2007.04.20
key words:
constructor 構造函數 method 方法 instance 實例
object 對象 modifier 修飾符 return type 返回類型
static method 靜態方法 superclass 超類 Inheritance 繼承
platypus 鴨嘴獸
我們說一個構造函數是方法就好比說澳洲鴨嘴獸是另一個哺乳動物一樣。 為了了解鴨嘴獸,知道其與其他的哺乳動物的差別對我們來說非常重要。同理,了解構造函數,知道構造函數與其他方法的區別對我們同樣重要。對于任何學習Java,尤其是為了獲得資格證書的學生來說,都需要知道這些區別。在這篇文章中,我將會一一道來。在文章結尾,Table1 總結了constructor(構造函數)和method(方法)的重要區別。
Purpose and Function (目的與功能)
構造函數都有一個目的:創建一個類的實例。也可以叫做創建一個對象,如下:
Platypus p1 = new Platypus();
相比之下,方法(method)的目的顯得更為普通. 一個方法的基本功能就是為了執行Java的代碼.
Signature differences(簽名區別)(Signature 不知道怎么翻譯好)
構造函數(constructors)和方法(methods)在以下三個方面存在差別:
· 修飾符 (modifiers)
· 返回類型(return type)
· 名字 (name)
像方法一樣,構造函數可以有任意一種訪問修飾符(access modifiers):公共的(public),保護的(protected),私有的(private)或者沒有(常被稱為package或者friendly)。不同于方法的是,構造函數只能被訪問修飾符進行限定。因此,構造函數不能是abstract, static, final, natice or synchronized的。
兩者的返回類型(return type)也是截然不同的。方法可以擁有任何有效的返回類型,或者方法沒有返回值,這種情況下方法的返回類型為void。構造函數沒有返回類型,也沒有void。
最后,構造函數和方法在取名方面也有很大的不同。構造函數名字與其類名(class name)相同;按照慣例,方法使用其他與類名不相同的名字。如果Java程序員遵循通常慣例,方法名將會以小寫字母開頭,構造函數名字以大寫字母開頭。并且,因為與類名相同,構造函數名字通常是個名詞,方法名字是個動詞。
The use of "this" (this的使用)
構造函數和方法使用關鍵字 this 差別很大。
方法中的 this 指的是執行該方法的類的實例(instance)。靜態方法(static method)不使用 this 。因為靜態方法不屬于任何一個類的實例,所以 this 無所指向。靜態方法總體上屬于一個類而非一個類的實例。
構造函數中的 this 指的是,在同一個類中擁有不同的參數列表的另一個構造函數。代碼如下:
public class Platypus {
String name;
Platypus(String input) {
name = input;
}
Platypus() {
this("John/Mary Doe");
}
public static void main(String args[]) {
Platypus p1 = new Platypus("digger");
Platypus p2 = new Platypus();
}
}
在代碼中,有兩個構造函數。
第一個構造函數通過一個String參數input給name進行賦值。
第二個構造函數沒有參數,通過默認的名字"John/Mary Doe"來調用第一個構造函數。
如果在構造函數中使用 this,則必須在構造函數的第一行代碼當中,否則編譯器會報錯。
注:在我這里的報錯信息為 Constructor call must be the first statement in a constructor。
The use of "super"(super的使用)
方法和構造函數使用 super 的時候,指的都是超類(superclass),但也有所不同。
方法中使用 super 將會執行超類中被覆蓋的方法,如下所示:
class Mammal {
void getBirthInfo() {
System.out.println("born alive.");
}
}
class Platypus extends Mammal {
void getBirthInfo() {
System.out.println("hatch from eggs");
System.out.print("a mammal normally is ");
super.getBirthInfo();
}
}
在上面代碼中,super.getBirthInfo() 將會調用超類 Mammal 中被覆蓋的方法 getBirthInfo().
構造函數中使用 super 將會調用超類中的構造函數。
如果在構造函數中使用 super,則必須在構造函數的第一行代碼當中,否則編譯器會報錯。
注:在我這里的報錯信息為 Constructor call must be the first statement in a constructor。
代碼如下:
public class SuperClassDemo {
SuperClassDemo() {}
}
class Child extends SuperClassDemo {
Child() {
super();
}
}
Complier -- supplied code(編譯器提供的代碼)
當編譯器自動為構造函數提供代碼的時候,Java初學者可能會感到困惑。如果你的類中沒有構造函數,編譯器將會為你自動提供一個沒有參數的構造函數。如果你的代碼如下:
public class Example {}
功能上它等同于如下代碼:
public class Example {
Example() {}
}
如果在你的構造函數的第一行代碼當中沒有使用 super,那么編譯器會自動為你提供代碼,插入 super。
如果你的代碼如下:
public class TestConstructors {
TestConstructors() {}
}
功能上它等同于如下代碼:
public class TestConstructors {
TestConstructors() {
super();
}
}
初學者可能會有疑問:TestConstructors 并沒有繼承任何類,為什么它會調用父類的構造函數呢?
答案是:在 Java 中如果沒有顯示的繼承一個類,則默認為繼承自 Object 類。
如果沒有顯示的聲明一個構造函數,編譯器自動提供一個沒有參數的構造函數;如果一個構造函數沒有顯示的 super 調用,編譯器自動提供一個沒有參數的 super 調用。所以下面的兩段代碼在功能上是等價的:
public class Example {}
和
public class Example {
Example() {
super();
}
}
Inheritance(繼承)
下面情況有什么不對?
律師閱讀類A的遺囑。所有家庭成員圍坐在大會議桌旁,并且有些人在輕聲嗚咽。律師說到:“我,類A,頭腦清楚身體健康,將我所有的構造函數留給我的孩子”。
問題是構造函數不是通過繼承得到的。然而幸運的是,子類可以自動的繼承父類所有的方法,所以子類并不是一無所有。
記住:Java 方法可以通過繼承得到,而構造函數不行。看下面代碼:
public class Example {
public void sayHi {
system.out.println("Hi");
}
Example() {}
}
public class SubClass extends Example {
}
類 SubClass 自動繼承父類的 sayHi 方法。然而,構造函數 Example() 不會被類 SubClass 所繼承。
Summarizing the differences
構造函數與方法的區別就像鴨嘴獸與典型的哺乳動物一樣。尤其是在目的(purpose),簽名(signature),和 this 與 super 的使用方面。另外,在繼承和編譯器提供代碼方面也有很大差異。記住所有的區別可能會非常辛苦,所以下面提供的一個表格,簡單的概括了重要的差異方面。
Topic |
Constructors |
Methods |
Purpose |
Create an instance of a class |
Group Java statements |
Modifiers |
Cannot be abstract, final, native, static, or synchronized |
Can be abstract, final, native, static, or synchronized |
Return type |
No return type, not even void |
void or a valid return type |
Name |
Same name as the class (first letter is capitalized by convention) -- usually a noun |
Any name except the class. Method names begin with a lowercase letter by convention -- usually the name of an action |
this |
Refers to another constructor in the same class. If used, it must be the first line of the constructor |
Refers to an instance of the owning class. Cannot be used by static methods |
super |
Calls the constructor of the parent class. If used, must be the first line of the constructor |
Calls an overridden method in the parent class |
Inheritance |
Constructors are not inherited |
Methods are inherited |
Compiler automatically supplies a default constructor |
If the class has no constructor, a no-argument constructor is automatically supplied |
Does not apply |
Compiler automatically supplies a default call to the superclass constructor |
If the constructor makes no zero-or-more argument calls to super, a no-argument call to super is made |
Does not apply |
原文:
http://www.javaworld.com/jw-10-2000/jw-1013-constructors.html
馬嘉楠
jianan.ma@gmail.com
posted on 2007-04-20 18:01
馬嘉楠 閱讀(1346)
評論(3) 編輯 收藏 所屬分類:
外文翻譯