Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/oop/2.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
这是将Java接口转换为Scala的正确方法吗?_Java_Oop_Scala_Inheritance_Traits - Fatal编程技术网

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

这是将Java接口转换为Scala的正确方法吗?,java,oop,scala,inheritance,traits,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(ar

我开始学习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方式”?

编辑:


我将把第二个问题转移到一个新的线程。

对于1:1映射,那些
var
s应该更改为
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) 歧视工会。(又名总和类型。)

请参阅以了解此概念。当以这种方式建模时,您的示例可能是这样的:

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) 输入类模式

这是丹尼尔·索布拉尔关于这个话题的一篇好文章。您可以通过谷歌搜索术语type class、pattern、Scala、implicits等来挖掘更多信息。如果问题是用type class pattern建模的,则代码可能是这样的:

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);"
}
对于您的问题,原始方法和判别联合方法似乎是最好的建模解决方案。

为什么我在trait中声明变量后,还要在类中再次声明变量

因为您声明了方法
printInstruction
的签名,但没有说明它的作用。在
中,由于它不是
抽象类
,因此应定义所有函数。
顺便说一句,您可以直接在
trait编译器中定义
打印指令
,如果它在每个实现中都应该这样做的话。

最惯用的方法是对抽象属性使用
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);"
}

或者至少是
val
而不是
var
。谢谢你的回答,但我不想要1:1的映射,我想要最好的Scala方法来解决我的“问题”。我试图学习Scala的方法,而不仅仅是Java思维模式下的Scala语法。@Farmor,这里使用的技术在Scala中也被广泛使用。并非所有来自Java的技术都会因为在Java中使用而过时。@Farmor,或者您可以使用有区别的联合。让我扩展我的答案。也许我误解了Scala,但var不是一个变量,不是一个方法吗?还是Scala将变量视为方法?printInstruction不应该是一个方法,而应该是一个字符串字段,每个编译器都有不同的字符串。我认为误导我们的是您编写了
getPrintInstruction()
,括号是您编写了一个方法的标志(在java中,它是一个方法)。所以变量不同于函数,因为你可以设置和获取变量,基本上你不能设置函数,你可以用它来“创建”结果。你声明的变量直到你给它一个值才被定义。尝试在不为printInstruction提供值的情况下扩展编译器。如果你给它一个非字符串的值,比如42,你可以看到它并不是一个真正的重新声明。我不明白,请容忍我:),它似乎是定义的,因为如果我给它42,编译器会写:重写字符串类型的trait编译器中的变量printInstruction;变量printInstruction具有不兼容的类型您在变量定义中遇到错误,因为超类中的变量声明具有不兼容的类型。我们声明一个类型为String的变量printInstruction,并将该值的值定义为例如“hi”。与java相反,您不能忽略定义并获得默认值(null或0)。在这方面,“var x:String”是抽象的,就像方法是抽象的一样;但是这个词没有被使用,它是未定义的。我想我们彼此误解太多了,但是我得到了我粘贴它只是为了告诉你编译器知道它是一个字符串,因此它不是未定义的。谢谢你的解释,虽然我已经开始了一个新的线程,因为这是很长的评论字段。
trait Compiler {
  def printInstruction: String
}

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

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