试图理解scala的特质
我是斯卡拉的新手。我不太理解scala的特点。我读过它类似于java接口,但方法不必是抽象的。但是我如何声明scala特性并在下面的代码中实例化它呢。顺便说一句,下面的代码工作正常试图理解scala的特质,scala,interface,traits,Scala,Interface,Traits,我是斯卡拉的新手。我不太理解scala的特点。我读过它类似于java接口,但方法不必是抽象的。但是我如何声明scala特性并在下面的代码中实例化它呢。顺便说一句,下面的代码工作正常 trait fooable { def foo: Unit = { println("This is foo") } } object Main { def main(args: Array[String]): Unit = { println("This i
trait fooable {
def foo: Unit = {
println("This is foo")
}
}
object Main {
def main(args: Array[String]): Unit = {
println("This is morking")
val foo = new fooable{}
foo.foo
}
}
输出-
这是黎明
我是福
提前感谢。当您实例化一个trait时,您创建了一个匿名类的实例,该实例扩展了该trait,其工作方式与在java中创建匿名接口类的方式相同。如果您在trait fooable中有任何未实现的方法,编译器会在您创建匿名类时强制您当场实现它们。当您实例化一个trait时,您创建了一个匿名类的实例,该实例扩展了该trait,其工作方式与在java中创建匿名接口类的方式相同。如果您在trait fooable中有任何未实现的方法,编译器会在您创建匿名类时强制您当场实现它们。Scala trait比Java接口和抽象类都更通用 您可以使用trait作为接口,您可以使用它存储一些实现,您可以简单地使用它定义一个通用的超级类型:
trait Message
case class Text(text: String) extends Message
case class Data(data: ByteString) extends Message
一个类中可以“混合”多种特征:
class MyClass extends TraitA with TraitB with TraitC
如果与同名方法的任何冲突通过简单规则解决:最后一个特征优先。此代码:
trait TraitA { def print() { println("A") } }
trait TraitB { def print() { println("B") } }
trait TraitC { def print() { println("C") } }
new MyClass.print()
将打印C
无法实例化Scala特性。在示例中,您正在创建一个匿名类。如果向trait中添加抽象方法,它将不会编译
无关注:
在有副作用的方法中编写大括号是一种很好的做法。你的方法foo有一个副作用:它打印一些东西。因此,您应该编写foo。Scala特性比Java接口和抽象类更通用 您可以使用trait作为接口,您可以使用它存储一些实现,您可以简单地使用它定义一个通用的超级类型:
trait Message
case class Text(text: String) extends Message
case class Data(data: ByteString) extends Message
一个类中可以“混合”多种特征:
class MyClass extends TraitA with TraitB with TraitC
如果与同名方法的任何冲突通过简单规则解决:最后一个特征优先。此代码:
trait TraitA { def print() { println("A") } }
trait TraitB { def print() { println("B") } }
trait TraitC { def print() { println("C") } }
new MyClass.print()
将打印C
无法实例化Scala特性。在示例中,您正在创建一个匿名类。如果向trait中添加抽象方法,它将不会编译
无关注:
在有副作用的方法中编写大括号是一种很好的做法。你的方法foo有一个副作用:它打印一些东西。因此,您应该编写foo。事实上,您的代码应该工作良好,并输出与您提到的相同的结果。然而,这里需要注意的重要一点是,TRAIT永远不能被实例化。这与Java接口永远无法实例化的概念是一样的 当scala编译器注意到代码foo=new fooable{}时,它会在内部创建一个匿名类,该类扩展了您的fooable特性,因此它会由于继承而继承foo方法。请参阅以下代码段:
scala> val foo = new fooable{}
foo: fooable = $anon$1@277c0f21
因此,当您调用foo.foo时,它在运行时调用匿名的classi.e$阿农$1@277c0f21继承的方法foo
同样的理解也适用于Java,以下是完全合法的Java代码:
Runnable r = new Runnable() {
public void run() {
System.out.println(" Cat");
}
};
r.run()
学习愉快 实际上,您的代码应该运行良好,并输出与您提到的相同的结果。然而,这里需要注意的重要一点是,TRAIT永远不能被实例化。这与Java接口永远无法实例化的概念是一样的 当scala编译器注意到代码foo=new fooable{}时,它会在内部创建一个匿名类,该类扩展了您的fooable特性,因此它会由于继承而继承foo方法。请参阅以下代码段:
scala> val foo = new fooable{}
foo: fooable = $anon$1@277c0f21
因此,当您调用foo.foo时,它在运行时调用匿名的classi.e$阿农$1@277c0f21继承的方法foo
同样的理解也适用于Java,以下是完全合法的Java代码:
Runnable r = new Runnable() {
public void run() {
System.out.println(" Cat");
}
};
r.run()
学习愉快 Scala特征是抽象的,无法实例化。在上面的代码中,其实例化为
val foo = new fooable{}
而不是
val foo = new fooable()
花括号创建了一些匿名类,该类不可食,但为空
什么是特质
特性类似于任何其他语言中的接口。Scala允许在定义和构造期间实例化特征。例如,如果我们有一个trait和一个抽象类
trait testTrait {
}
abstract class BaseClass {}
class Derive extends BaseClass with testTrait {
}
// ---------------------- OR----------------------
// Traits can be used during instantiation
class Derive extends BaseClass {
}
val classInst = new Derive with testTrait
特征也可以使用multiple with trait链接Scala特征是抽象的,不能实例化。在上面的代码中,其实例化为
val foo = new fooable{}
而不是
val foo = new fooable()
花括号创建了一些匿名类,该类不可食,但为空
什么是特质
特性类似于任何其他语言中的接口。Scala允许在定义和构造期间实例化特征。例如,如果我们有一个trait和一个抽象类
trait testTrait {
}
abstract class BaseClass {}
class Derive extends BaseClass with testTrait {
}
// ---------------------- OR----------------------
// Traits can be used during instantiation
class Derive extends BaseClass {
}
val classInst = new Derive with testTrait
还可以使用多个trait将trait链接起来可能与您重复
无法实例化特征。您所做的是创建trait的匿名内部子类,并实例化它,就像在Java中一样。顺便说一句:特性实际上根本不像接口。他们更像是混血儿。事实上,Scala的特征更像是混血儿而不是特征,所以术语特征有点用词不当。我明白你的意思了。感谢您无法实例化特征的可能副本。您所做的是创建trait的匿名内部子类,并实例化它,就像在Java中一样。顺便说一句:特性实际上根本不像接口。他们更像是混血儿。事实上,Scala的特征更像是混血儿而不是特征,所以术语特征有点用词不当。我明白你的意思了。谢谢