有java背景的人,很清楚java是如何定義構造方法以及繼承的。在scala里面,繼承和java有些相似。但是構造方法的定義,就不大一樣了,應該說是差別還是很大的。在java里面,定義構造方法,就是定義一個沒有返回值類型的與類同名的方法。
如下:

1 package com.shihuc; 2 3 public class Person 4 { 5 private String lastName; //姓 6 private String firstName; //名 7 private Person spouse; //配偶的Person對象 8 public Person(String fn, String ln, Person s) 9 { 10 lastName = ln; firstName = fn; spouse = s; 11 } 12 public Person(String fn, String ln) 13 { 14 this(fn, ln, null); //未婚時沒有配偶 15 } 16 public String getFirstName() 17 { 18 return firstName; 19 } 20 public String getLastName() 21 { 22 return lastName; 23 } 24 public Person getSpouse() 25 { 26 return spouse; 27 } 28 public void setSpouse(Person p) 29 { 30 spouse = p; 31 } 32 public String introduction() 33 { 34 return "我的名字是," + firstName + " " + lastName + 35 (spouse != null ? 36 " 對方的名字是," + spouse.firstName + " " + spouse.lastName + " 。" : 37 " 。"); 38 } 39 }
但是,scala里面,可以看到:

1 package lession2 2 3 class Person(fn: String, ln: String, s: Person){ 4 val firstname = fn 5 val lastname = ln 6 var suporse = s 7 8 println("primary constructor") 9 10 def this(fn : String, ln : String) { 11 this(fn, ln, null) 12 } 13 14 println("I am testing code") 15 16 def introduction() : String = { 17 return "我的名字是, " + lastname + " " + firstname + 18 (if (suporse != null) { 19 " 對方的名字是, " + suporse.lastname + " " + suporse.firstname + "。" 20 }else { 21 "。"; 22 }) 23 } 24 } 25 26 object PersonTest{ 27 def main(args: Array[String]){ 28 var p = new Person("shihu", "CHENG") 29 println(p.introduction()) 30 } 31 }
雖然scala的寫法變得比java簡潔了很多,這個是值得表揚的,但是構造函數的定義就有很大的不同。
1. 先說主構造函數,也就是英文資料中說的primary constructor,它是和類的定義混雜在一起的,即定義類的時候,就指明了這個類的成員變量參數,還有,就是在類中,除了def定義的成員函數之外的所有操作,都可以看作是構造函數的行為組成部分,不管是變量賦值還是函數調用。而java的類定義和構造函數的定義是分開的。
2. 再說派生的構造函數,即java中可以定義多個構造函數,這點,在java里非常簡單,就是方法的重載唄。但是,在scala里面,要定義多個構造方法,就必須直接或則間接的調用主構造函數。而且調用的時候,必須通過關鍵字this來操作。正如上面scala代碼中的輔助構造函數:
1 def this(fn : String, ln : String) { 2 this(fn, ln, null) 3 }
需要注意的是,輔助構造函數名必須是this,而且必須調用主構造函數實現參數的傳遞(直接或則間接,本例子是直接調用,因為只有一個輔助構造函數)。
3. 在scala中,若有繼承,那么,只有主構造函數才能將參數的值傳遞到父類的構造函數中去。
4. 在scala中,若子類繼承了父類,但是想在子類中重寫父類的某個函數,則在子類中必須用關鍵字override對父類的函數進行改寫, 否則會出現語法錯誤。要想調用父類的同名函數,可以通過super關鍵字進行,這點與java是一致的。