2011-04-25 89 views
11
class PasswordCaseClass(val password:String) 
trait PasswordTrait { self:PasswordCaseClass => 
    override def password = "blue" 
} 

val o = new PasswordCaseClass("flowers") with PasswordTrait 

是否可以用PasswordTrait提供的內容覆蓋PasswordCaseClasspassword?現在,我收到此錯誤:我可以用特徵中的方法重寫一個scala類方法嗎?

e.scala:6: error: overriding value password in class PasswordCase 
Class of type String; 
method password in trait PasswordTrait of type => java.lang.String needs to be a stable, 
immutable value 
val o = new PasswordCaseClass("flowers") with PasswordTrait 
      ^
one error found 

我希望能有這樣的事情:

class User(val password:String) { 
} 

trait EncryptedPassword { u:User => 
    def password = SomeCriptographyLibrary.encrypt(u.password) 
} 

val u = new User("random_password") with EncryptedPassword 
println(u.password) // see the encrypted version here 

回答

19

您可以用val覆蓋def,但不能以其他方式進行。 A val意味着保證 - 它的價值是穩定和不可變的 - def沒有。

8

這爲我工作(有一些修改):

trait PasswordLike { 
val password: String 
} 

class PasswordCaseClass(val password:String) extends PasswordLike 

trait PasswordTrait extends PasswordLike { 
override val password: String = "blue" 
} 

然後:

scala> val o = new PasswordCaseClass("flowers") with PasswordTrait 
o: PasswordCaseClass with PasswordTrait = [email protected] 

scala> o.password 
res1: String = blue 
+0

但是,如果我使用字段或方法,Scala應該不會無動於衷嗎? – Geo 2011-04-25 08:37:06

+3

那麼,關於重寫,我認爲def可以被val重寫,但不是相反。 – 2011-04-25 09:02:58

3

您正嘗試用方法定義覆蓋該值。它根本沒有意義 - 它們有不同的語義。應該每個對象生命週期計算一次值(並存儲在最終的類屬性中)和方法可以多次計算。所以你試圖做的是以多種方式來制止班級的合同。

無論如何也有編譯器的錯誤 - 錯誤的解釋是完全不清楚的。

+2

錯誤表示在* value *'password'用* method *'password'重寫時出現錯誤:您必須使用「穩定的,不可變的值」。不明白爲什麼這是「完全不清楚」。 – gerferra 2011-04-25 09:53:48

+0

我認爲好的解釋應該是「val和def聲明之間的名稱衝突」。不要太認真 - 這只是非編譯器專家的意見。 – CheatEx 2011-04-25 10:11:52

+0

我認爲這個消息比原來的消息更令人困惑。 – 2011-04-25 12:38:50

相關問題