摘要:本文将简要介绍Java中的接口(interface),Java 8中接口default方法,以及Scala中的特质(trait),同时会比较Java接口与Scala特质的相似与差异。
1. Java 接口 (interface) 介绍
1.1 Java传统的接口 (interface)
Java接口是一系列方法的声明,是一些方法特征的集合,一个接口只有方法的特征没有方法的实现,因此这些方法可以在不同的地方被不同的类实现,而这些实现可以具有不同的行为(功能)。
Java接口本身没有任何实现,因为Java接口不涉及表象,而只描述public行为,所以Java接口比Java抽象类更抽象化。
Java接口的方法只能是抽象的和公开的,Java接口不能有构造器,Java接口可以有public、静态的和final属性。即接口中的属性可以定义为 public static final int value=5;
假设我们有用于记录日志的Logger接口,有两种不同的实现方式,一种是输出的到Console,一种是输出到文件。
以下为参考实现:
Logger接口 (interface):
publicinterface Logger {
//only public, static and final property is permitted
publicstaticfinalintmaxLength = 50;
//only public and abstract method
publicabstractvoid log(String msg);
}
ConsoleLogger输出到Console:
publicclass ConsoleLogger implements Logger {
@Override
publicvoid log(String msg) {
System.out.println(msg);
}
}
FileLogger输出到文件:
publicclass FileLogger implements Logger {
private PrintWriter fileOutput;
public FileLogger () {
try {
fileOutput = new PrintWriter("app。log");
} catch (FileNotFoundException e) {
e.printStackTrace();
}
}
@Override
publicvoid log(String msg) {
fileOutput.println(msg);
fileOutput.flush();
}
}
1.2 Java 8中的interface
Java 8 允许我们使用default关键字,为接口声明添加非抽象的方法实现。
publicinterface Logger {
//only public, static and final property is permitted
publicstaticfinalintmaxLength = 50;
//Java 8 interface default implementation
publicdefaultvoid log(String msg) {
//You could implement default log behavior here
//......
}
}
可以在实现类中改变它接口中的缺省行为和实现:
publicclass ConsoleLogger implements Logger {
//Change default log behavior here
@Override
publicvoid log(String msg) {
System.out.println(msg);
}
}
Java 8之后的interface可以包含包含abstract方法,也可以都是default方法。
2. Scala 特质 (trait) 介绍
Scala中的特质 (trait) 和Java 8中的接口 (interface) 比较类似,一个Scala类可以扩展一个或多个特质,Scala特质可以给出方法的缺省实现。
2.1 纯接口的特质
traitLogger {
//abstract method, but no abstract declare required
deflog(msg: String)
}
你不需要将方法声明为abstract,特质中未被实现的方法默认就是抽象的。
//Use extends but not implements
classConsoleLoggerextendsLogger {
//no override required
deflog(msg: String) {
println(msg)
}
}
在重写特质的抽象方法时不需要给出override关键字
2.2 带缺省实现的特质
traitConsoleLogger {
//with implementation
deflog(msg: String) { println(msg) }
}
带有实现方法的特质类似于Java 8接口中的缺省方法。
以下是如何使用这个特质的示例:
class Circle extends Shape withConsoleLogger {
def draw() {
log(“Draw a circle …”);
//draw circle here
……
}
}
在Scala中,我们说ConsoleLogger的功能被“混入”了Circle类中。
2.3 带有特质的对象
Scala可以在创建对象时添加特质,这是Java接口所不具备的特性。
缺省的log方法什么没做:
traitLogger {
deflog(msg: String) { }
}
下面使用这个特质的Class什么日志都不会被记录:
class Circle extends Shape withLogger{
def draw() {
log(“Draw a circle …”);
//draw circle here
}
}
你可以实现一个更好的Logger特质,并在创建Circle对象是动态“混入”此特质。
traitConsoleLoggerextendsLogger {
overridedeflog(msg: String) { println(msg) }
}
val circle1 = new CirclewithConsoleLogger
这样circle在调用draw方法时,ConsoleLogger的log方法会被执行。
类似的,你可以在另一个对象加入另外一个特质:
val circle2 = new CirclewithFileLogger
2.4 叠加在一起的特质
就像Java Class可以实现多个接口一样,Scala Class也可以叠加多个特质,一般来说,特质从最后一个开始被处理。
假设有如下的Logger trait定义,分别有3个trait扩展自Logger。
traitLogger {
deflog(msg: String) { }
}
traitConsoleLogger extends Logger {
overridedeflog(msg: String) { println(msg) }
}
traitTimestampLoggerextends Logger {
overridedeflog(msg: String) { super.log(new Date() + “ “ + msg) }
}
traitShortLoggerextends Logger {
val maxLength = 15
overridedeflog(msg: String) {
super.log( if(msg.length<= maxLength) msg else msg.substring(0,
maxLength-3) + “…” )
}
}
上述log方法都将修改过的msg传递给super.log.
实际上,super.log调用的是特质层级中的下一个特质,具体是哪一个,取决于特质添加的顺序。一般来说,特质从最后一个开始被处理。
可以通过如下方式添加混入特质:
val circle1 = new CirclewithConsoleLogger with TimestampLogger with ShortLogger
此例中,ShortLogger的log方法先被执行,然后才是TimestampLogger的log方法。
val circle2 = new CirclewithConsoleLogger with ShortLogger with TimestampLogger
此例中,TimestampLogger的log方法先被执行,然后才是ShortLogger的log方法。
3. Java接口 (interface) 与Scala特质 (trait) 比较
通过上面对Java接口和Scala特质的学习,我们发现它们之间有很多的相似性,同时也有差别。
相似性:
Java接口和Scala特质都可以包含抽象方法和具体实现;
Scala和Java一样都不允许类从多个超类继承,但分别可以叠加多个特质和实现多个接口;
差异性:
Java只能在Class层面添加接口的实现,Scala可以在Class和对象层面“混入”特质。Scala通过在对象层面动态“混入”特质,相比而言具有更大的灵活性。
相关推荐
1.Scala中没有接口(interface)的概念 2.特质用于在类之间共享程序接口和字段,类似Java接口 3.特质是字段和方法的集合,可以提供字段和方法实现 4.类和单例对象都可以扩展特质(extends) 5.特质不能被实例化,...
面向对象来看,接口并不属于面向对象的范畴,Scala是纯面向对象的语言,在Scala中,没有接口。Scala语言中,采用特质trait(特征)来代替接口的...在Scala中,Java中的接口可以当做特质使用。 object boke_demo01 { de
面向Java开发人员的Scala指南 面向Java开发人员的Scala指南
面向 Java 开发人员的 Scala 指南 Scala是一个结合面向对象与函数编程的新兴语言。
Learn Scala is split into four parts: a tour of Scala, a comparison between Java and Scala, Scala-specific features and functional programming idioms, and finally a discussion about adopting Scala in...
IBM:面向Java开发人员的Scala指南-p178.7z,IBM:面向Java开发人员的Scala指南-p178.7z
Then, we will provide a comparative analysis of Java and Scala. Finally, we will dive into Scala programming to get started with Scala. Chapter 2, Object-Oriented Scala, says that the object-oriented ...
本文是《A Scala Tutorial for Java programmers》英文的翻译. 本文仅在对Scala语言和其编译器进行简要介绍。本文的目的读者是那些已经具有一定编程经验,而想尝试一下Scala语言的人们。要阅读本文,你应当具有基础...
scala-js-java-time, 在JDK8中,java.time的Scala.js 实现 scalajs-java-time scalajs-java-time 是用于的java.time API的bsd许可 reimplementation,它支持在 Scala.js 项目中使用这里 API 。用法只需将以
面向 Java 开发人员的 Scala 指南系列.rar,面向 Java 开发人员的 Scala 指南系列.rar,面向 Java 开发人员的 Scala 指南系列.rar
JGSK, Java,Groovy,Scala,Kotlin 四种语言的特点对比
Martin Odersky 用他定义的匹萨语言给了 Java世界一个很大的冲击。尽管匹萨本身没有流行 但它展现了当把面向对象和函数型语言两种风格,技术地且很有品地混搭在一起时,就形成了 自然和强有力的组合。匹萨的设计成为...
Scala到Java 用Scala编写的简单工具,揭示了Scala编译器的奥秘。 从StdIn读取scala代码,并将其反编译的Java版本写入StdOut。 用法 确保您已安装Java 1.8和Maven 检出项目 在项目目录中调用mvn clean package 。 ...
博客配套文件,详细演示了在maven中如何混合编译java和scala共存的代码。
Java 到 Scala 插件(Scala IDE) 这是用于 Eclipse 的 Scala IDE 插件,可让您将 Java 转换为 Scala。 要使用它,请右键单击任何 Java 类、包或源文件夹,然后选择“转换为 Scala” 您还可以将 Java 代码复制到...
Scala功能的功能接口 一组用于scala.FunctionN的。 这些设计用于使用Java 8 lambda语法方便地构造Scala函数。 用法 import scala.concurrent.* ; import static scala.compat.java8.JFunction.* ; class Test { ...
word文档在压缩文件里,另有java+hadoop+scala+spark资料。(word文档内容比较粗糙,但能看懂)
面向Java开发人员Scala指南,Scala和servlet的比较 以及一些网上资料的整理,给大家分享分享!!!
赠送jar包:scala-java8-compat_2.11-0.7.0.jar; 赠送原API文档:scala-java8-compat_2.11-0.7.0-javadoc.jar; 赠送源代码:scala-java8-compat_2.11-0.7.0-sources.jar; 赠送Maven依赖信息文件:scala-java8-...
1.var,val和def三个关键字之间的区别 2.trait(特质)和abstract class(抽象类)的区别 3.object和class的区别 4.c