2011-06-03 61 views
7

我在scala中遇到了一個奇怪的問題。以下是我的代碼,類員工擴展類Person必須在scala中覆蓋val變量

但是這段代碼不能編譯,我有顯式定義firstName和lastName爲val變量。這是爲什麼 ?這是否意味着我必須在基類中重寫val變量?目的是什麼?

class Person(firstName: String, lastName: String) { 

} 

class Employee(override val firstName: String, override val lastName: String, val depart: String) 
    extends Person(firstName,lastName){ 

} 

回答

10

構造函數的輸入參數不是val,除非你說他們是。如果它們已經存在,爲什麼要覆蓋它們?

class Person(val firstName: String, val lastName: String) {} 
class Strange(
    override val firstName: String, override val lastName: String 
) extends Person("John","Doe") {} 
class Employee(fn: String, ln: String, val depart: String) extends Person(fn,ln) {} 

如果他們不瓦爾斯和你想丘壑,你並不需要重寫:

class Person(firstName: String, lastName: String) {} 
class Employee(
    val firstName: String, val lastName: String, val depart: String 
) extends Person(firstName,lastName) {} 
+10

這個答案回答一個問題的問題。我將嘗試回答。你必須在'Strange'類的'val'前面說'override'的原因是告訴編譯器你不打算引入一個新字段。 'override'的意思大致是「在這裏我聲明瞭一些已經在父類中聲明過的東西,並且不打算介紹一些不被繼承的東西」。如果沒有「覆蓋」,val就意味着「請創建一個公共的,只讀的字段」。但是Scala不允許兩個val字段具有相同的名稱。因此,「覆蓋」是強制性的。 – 2013-07-31 20:02:44

+0

@TheodoreNorvell - 我的觀點應該是,如果你只是用相同的字段來擴展原始類,那麼就沒有理由去創建覆蓋。只需將它們作爲參數傳遞,並讓超類val成爲val。 – 2013-07-31 20:41:24

+0

@RexKerr好的,這是一個很好的觀點。你在問,「爲什麼有'覆蓋val'?我回答說:「爲什麼'override'因爲你有'val'?」。在我編寫的代碼中,我有類似的情況,但在我的情況下,子類是一個case類,所以構造函數參數自動爲val。在這種情況下,編譯器會給出一個錯誤消息,除非'override'關鍵字在那裏,並且大概出於語法原因,它還需要'val'關鍵字。唯一的缺點是這兩個額外的單詞,並且該字段被初始化兩次。 – 2013-08-02 12:40:16

0

除非我誤解了你的意圖,否則以下是如何擴展Person

Welcome to Scala version 2.8.0.final (Java HotSpot(TM) Client VM, Java 1.6.0_21). 
Type in expressions to have them evaluated. 
Type :help for more information. 

scala> class Person(firstName: String, lastName: String) 
defined class Person 

scala> class Employee(firstName: String, lastName: String, depart: String) extends Person(firstName, lastName) 
defined class Employee 
6

由於構造函數的參數有沒有人VAL/VAR聲明,因爲人是沒有的情況下類,參數將不類人,只是構造函數參數的成員。編譯器基本上是告訴你:哎,你說,那firstName和lastName的成員,其覆蓋/重新定義從基類繼承的東西 - 但並沒有什麼,只要我可以告訴...

class Person(val firstName: String, val lastName: String) 
class Employee(fn: String, ln: String, val salary: BigDecimal) extends Person(fn, ln) 

你不需要在這裏聲明firstName/lastName作爲覆蓋,順便說一句。簡單地將這些值轉發給基類的構造函數就可以實現。

1

您也可以考慮重新設計超類的特性儘可能。例如:

trait Person { 
    def firstName: String 
    def lastName: String 
} 

class Employee(
    val firstName: String, 
    val lastName: String, 
    val department: String 
) extends Person 

甚至

trait Employee extends Person { 
    def department: String 
} 

class SimpleEmployee(
    val firstName: String, 
    val lastName: String, 
    val department: String 
) extends Employee