Dmi*_*tri 6 java inheritance overriding scala traits
我是Scala的新手(来自Ruby世界).
而且我对Scala中的"traits"概念感到好奇(如果我理解正确的话,它应该〜类似于ruby中的模块).
这是一个用例.
假设我有一个User像这样定义的类:
class User {
def password() : String = "generating a password (default)"
}
Run Code Online (Sandbox Code Playgroud)
假设我有一个特性SecurePasswords,我想用它"覆盖" User类中定义的密码方法.
trait SecurePasswords {
def password() : String = "generating a secure password (non-default)"
}
Run Code Online (Sandbox Code Playgroud)
并且,假设,我希望它适用于User类的实例,而不是适用于整个类本身.
val a = new User
val b = new User with SecurePasswords
a.password() # generating a password (default)
b.password() # generating a secure password (non-default)
Run Code Online (Sandbox Code Playgroud)
现在这是我期望的理想输出,但是,我得到了不同的错误,如" anonymous class inherits conflicting members ... (Note: this can be resolved declaring etc etc ...)"
这可以在Scala中完成,或者我要求太多/做一些非常奇怪的事情?是否可以做任何其他类定义,例如UserWithSecurePassword extends User
谢谢大家!
PS如果您想知道"为什么?",只需假设系统中包含许多需要密码的实体(可能还有安全密码),因此可以在很多地方使用该特征.
Dan*_*etz 11
两种方法定义之间的冲突是因为您没有使它们成为"相同的方法".你所做的就是让它们巧合地拥有相同的名称,参数和返回类型.
要使它们真的是相同的方法,以便可以覆盖另一个,在同一个地方定义它们:
trait HasPassword {
def password(): String
}
class User extends HasPassword {
override def password(): String = "generating a password (default)"
}
trait SecurePassword extends HasPassword {
override def password(): String = "generating a password (non-default)"
}
new User with SecurePassword
Run Code Online (Sandbox Code Playgroud)
通过在特征被定义HasPassword,然后重写(代替doppleganged或鸭类型的)中User和SecurePassword,Scala的理解这是真正被重新定义的方法相同.因此,当您混入时SecurePassword,它可以覆盖该password()方法User.
除了我之前的回答 - 一种完全不同的方式来获得你想要的是将密码函数传递给User类,而不是使用traits:
class User(pw: ()=>String=default) {
def password = pw
}
val default = () => "generating a password (default)"
val secure = () => "generating a secure password (non-default)"
val a = new User()
val b = new User(secure)
a.password() // generating a password (default)
b.password() // generating a secure password (non-default)
Run Code Online (Sandbox Code Playgroud)
如图所示,您可以使用默认参数来避免在默认情况下指定密码函数.