Scala抽象类翻译成Java



Scala最近给我带来了很多麻烦,因为我在互联网上找不到信息。由于Scala用一组无限术语定义了自己的语言(我还不知道),因此很难获得信息。

我在StackOverflow上就Scala和Java之间的翻译提出了一些问题,在最后一个问题中我说我将放弃这种方法。然而,我想了解正在发生的事情。

想象一下Scala类:

abstract class Block(n: String) {
    require(n != null)
    val name = n
    var log: ArrayList[String]
    var inputs: ArrayList[Input[_]]
    var outputs: ArrayList[Output[_]]
    def newValue
}

到目前为止还不错。问题是:

我无法访问类字段(是的,我尝试了this.inputs())。可能是因为它是这样翻译的:

public abstract class pt.thesis.tiago.Block 
    extends java.lang.Object implements  scala.ScalaObject{
    public java.lang.String name();
    public abstract java.util.ArrayList log();
    public abstract void log_$eq(java.util.ArrayList);
    public abstract java.util.ArrayList inputs();
    public abstract void inputs_$eq(java.util.ArrayList);
    public abstract java.util.ArrayList outputs();
    public abstract void outputs_$eq(java.util.ArrayList);
    public abstract void newValue();
    public pt.thesis.tiago.Block(java.lang.String);
}

为什么每一件事都是抽象的?难道我不能像Java一样,只做我想要的东西是抽象的吗?

关于学习Scala的材料,我在阅读Martin Odersky(Scala的创建者)、Lex Spoon和Bill Venners的《Scala编程》时学到了很多。此外,docs.scala-lang.org上有很多不错的信息,还有一个相当不错的scala之旅。

关于术语,我不认为Scala发明了那么多术语。这些术语可能来自你不熟悉的语言(Erlang、Haskell、ML等),或者在其他语言中没有得到太多讨论的概念,比如类型论。

这里的一般原则是Scala是一种非常规则的语言。事实上,Martin想让它变得更简单、更有规律。

在Java中,只有方法可以是抽象的。在Scala中,基本上类的任何成员都可以是抽象的。在Scala中,为了使一个项抽象化,您可以省略它的定义。因此,语句var log: ArrayList[String]实际上创建了一个抽象的var,而不是用null初始化的混凝土条。是的,这与您对Java的期望不同。但它使Scala作为一个整体成为了一种更加常规的语言。

abstract class Foo {
  type SomeType               // abstract type
  val someVal: SomeType       // abstract val
  var someVar: SomeType       // abstract var
  def someMethod(v: SomeType) // abstract method
}

如果您真的想创建一个初始化为null的字段,那么就用_初始化它。这将创建具体的变量,而不是抽象的变量。

每一件事都不是抽象的:名称不是抽象的。

事实上,由于它是一个抽象类,您可以有一些已声明但未定义的值,这些值本身将被标记为抽象。因此,如果你不想"输入"是抽象的,只需定义它们:

var inputs = ArrayList[Input[_]]()

编辑:关于评论中的常规问题,您仍然可以使用默认值(将为空):

abstract class Input[Type]{ 
  var value:Type = _; 
}

看看这意味着什么"分配"_"到scala中的字段?以及获取更多信息的最佳答案。

最新更新