这是将Java接口转换为Scala的正确方法吗?

时间:2012-01-27 12:28:08

标签: java oop scala inheritance traits

我开始学习Scala,我将做一个简单的交叉编译器。

我会支持一些像print这样的指令。

注意:代码片段未经过测试或编译 这是我在JAVA中所做的。

public interface Compiler{
 String getPrintInstruction();
}

public class JavaCompiler implements Compiler{
 public String getPrintInstruction(){
  return "System.out.print(arg0);"
 }
}

public class ScalaCompiler implements Compiler{
 public String getPrintInstruction(){
  return "print(arg0);"
 }
}

代码段是否在正确的“Scala方式”下方?

trait Compiler {
  var printInstruction: String
}
class JavaCompiler extends Compiler {
  var printInstruction = "System.out.print(arg0);"
}
class ScalaCompiler extends Compiler {
  var printInstruction = "print(arg0);"
}

修改

我会将我的第二个问题转移到一个新的主题。

3 个答案:

答案 0 :(得分:2)

对于1:1映射,这些var应更改为def s。

trait Compiler {
  def printInstruction: String
}

class JavaCompiler extends Compiler {
  def printInstruction = "System.out.print(arg0);"
}

class ScalaCompiler extends Compiler {
  def printInstruction = "print(arg0);"
}

def声明了一种方法。当您不提供实现时,它将成为一种抽象方法。

修改

这里使用的技术是一种有效且有用的技术。或者,您可以使用以下两种技术之一来模拟您的问题。

1)受歧视的工会。 (又名总和类型。)

请参阅this excellent article以了解此概念。这就是你的例子在以这种方式建模时的样子:

sealed trait Compiler {
  def printInstruction: String = this match {
    case JavaCompiler => "System.out.print(arg0);"
    case ScalaCompiler => "print(arg0);"
  }
}

case object JavaCompiler extends Compiler
case object ScalaCompiler extends Compiler

2)输入类模式。

Here是Daniel Sobral关于此主题的精彩文章。您可以通过Google搜索术语类型类,模式,Scala,implicits等来挖掘更多内容。如果问题是使用类型类模式建模的话,这就是您的代码的样子:

trait Compiler[C] {
  def printInstruction(c: C): String
}

case object JavaCompiler

implicit object JavaCompilerIsCompiler extends Compiler[JavaCompiler.type] {
  def printInstruction(c: JavaCompiler.type): String = "System.out.print(arg0);"
}

case object ScalaCompiler

implicit object ScalaCompilerIsCompiler extends Compiler[ScalaCompiler.type] {
  def printInstruction(c: ScalaCompiler.type) = "print(arg0);"
}

对于您的问题,原始方法和受歧视的联盟方法似乎是最好的建模解决方案。

答案 1 :(得分:1)

最惯用的方法是使用def表示抽象属性,使用val表示具体的只读属性。在统一访问原则下,val可用于实现方法:

trait Compiler {
  def printInstruction: String
}

class JavaCompiler extends Compiler {
  val printInstruction = "System.out.print(arg0);"
}

class ScalaCompiler extends Compiler {
  val printInstruction = "print(arg0);"
}

答案 2 :(得分:0)

当我在特征中声明变量时,为什么我必须再次在类中声明变量?

因为您声明了方法printInstruction的签名,但您没有说出它的作用。在class中,因为它不是abstract class,所以应该定义所有函数。 顺便说一句,如果在每个实现中都应该这样做,你可以直接在printInstruction中定义trait Compiler