Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/scala/17.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Scala 关于性格的问题_Scala_Traits - Fatal编程技术网

Scala 关于性格的问题

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

以下两种方法的区别是什么

1#

二,#

其中,
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()
  }
}