Scala 关于性格的问题
以下两种方法的区别是什么 1# 二,# 其中,Scala 关于性格的问题,scala,traits,Scala,Traits,以下两种方法的区别是什么 1# 二,# 其中,A是一个抽象类 >>编辑: 请解释以下具有可插拔飞行和嘎嘎声行为的Ducks示例: abstract class Duck { def fly(): Unit def quack(): Unit def swim() { println("Woodoowoodoowoodoo...") } } trait FlyingWithWings extends Duck { override def fly() { pr
A
是一个抽象类
>>编辑:
请解释以下具有可插拔飞行和嘎嘎声行为的Duck
s示例:
abstract class Duck {
def fly(): Unit
def quack(): Unit
def swim() {
println("Woodoowoodoowoodoo...")
}
}
trait FlyingWithWings extends Duck {
override def fly() {
println("Me can fliez! :D")
}
}
trait FlyingNoWay { self: Duck =>
def fly() {
println("Me cannot fliez! :(")
}
}
trait Quack extends Duck {
override def quack() {
println("Quack! Quack!")
}
}
trait MuteQuack { self: Duck =>
def quack() {
println("<< Silence >>")
}
}
class MallardDuck extends Duck with FlyingWithWings with MuteQuack
object Main {
def main(args: Array[String]) {
val duck = new MallardDuck
duck.fly()
duck.quack()
}
}
抽象类Duck{
def fly():单位
def quack():单位
def swim(){
println(“Woodoo…”)
}
}
有翼飞行的特性扩展了鸭子{
覆盖def fly(){
println(“我能飞!:D”)
}
}
trait FlyingNoWay{self:Duck=>
def fly(){
println(“我不能飞行!”:()
}
}
江湖郎中{
覆盖def-quack(){
println(“嘎嘎!嘎嘎!”)
}
}
鸭{self:Duck=>
def-quack(){
println(“>”)
}
}
MallardDuck类用MuteQuack扩展鸭子的翅膀
对象主体{
def main(参数:数组[字符串]){
瓦尔鸭=新马拉德鸭
鸭子飞
鸭子
}
}
输出:
我能飞!:D>
在第一个例子中,
B
是a
的特化。第二个例子意味着特质B
必须始终混合到某个东西中,即a
的子类型(可以是类、特质或任何其他类型).在第二种情况下,B不能用于预期A的地方,它只是被设计为“附加”到某个A。因此,例如,在第一种情况下,A可以是抽象的,B可以实现缺少的方法,使其成为可实例化的类型。在第二种情况下,这是不可能的,您需要“完整的A”,然后才添加一些功能
因此,你可以考虑“适合于…”关系,而不是“是…”关系。没有一个特征可以扩展一个类。我不知道,但我在REPL中试用了它,它是有效的。不过,直系祖先中不能有多个类,所以你不能获得多重继承(这就是为什么我认为你不能让trait扩展类)。看一个重复的,它本身就是一个应该优先选择哪一个的重复?为什么?这取决于你是否真的扩展了基本trait。例如,如果你有一个trait图,一个新的trait ColoredGraph显然“是一种”(新的类型)graph and应该扩展基本特性。另一方面,如果您使用findCycles方法添加特性,则此特性仅在与graph一起使用时才有意义,但它不会创建新的图形类型,它只是添加了一些功能,因此在本例中,您将选择具有self类型的第二个版本。对于某些情况,差异是没有意义的我不太清楚,但如果你有一些经验,你会发现哪个版本更适合你的设计。我想你没有理解我。让我试着重新表述一下。在我的问题中,
A
是一个抽象类,而不是特征
。在我包含的示例中,可以以两种方式插入(或混合)行为。(FlyingWithWings
使用扩展名,而MuteQuack
使用自类型注释。)那么,什么时候我应该选择一种方式而不是另一种方式,为什么?这不是真实世界的例子,但我想说,在这里延伸看起来更自然:带翅膀飞翔和江湖郎中更详细地说明了鸭子是什么。还有另一种解释涉及依赖性注射(但我认为这只是它们的一个用例):我发现:“有时候,一个trait能够使用它所混合到的类的字段或方法是很有用的,这可以通过为trait指定一个self类型来实现。”()
trait B { self: A =>
}
abstract class Duck {
def fly(): Unit
def quack(): Unit
def swim() {
println("Woodoowoodoowoodoo...")
}
}
trait FlyingWithWings extends Duck {
override def fly() {
println("Me can fliez! :D")
}
}
trait FlyingNoWay { self: Duck =>
def fly() {
println("Me cannot fliez! :(")
}
}
trait Quack extends Duck {
override def quack() {
println("Quack! Quack!")
}
}
trait MuteQuack { self: Duck =>
def quack() {
println("<< Silence >>")
}
}
class MallardDuck extends Duck with FlyingWithWings with MuteQuack
object Main {
def main(args: Array[String]) {
val duck = new MallardDuck
duck.fly()
duck.quack()
}
}