从接口转换为特征

时间:2014-06-12 20:27:23

标签: java scala

以下是我如何使用Java接口构建实现一项功能的通用契约的示例:

package main.java;

public class Main {

    interface Calculate {
        public int run();
    }

    private class Calc1 implements Calculate {

        @Override
        public int run() {
            return 1;
        }

    }

    private class Calc2 implements Calculate {

        @Override
        public int run() {
            return 0;
        }

    }

    public static void main(String args[]){

        Main m = new Main();

        Calculate c = m.new Calc1();
        System.out.println(c.run());

        c = m.new Calc2();
        System.out.println(c.run());


    }

}

转到Scala特征是我如何重新实现上述相同的逻辑:

package main.scala

object traitsfun {
  println("Welcome to the Scala worksheet")       //> Welcome to the Scala worksheet

  trait Calc {
    def run: Int
  }

  class Calc1 extends Calc {
    override def run = 1
  }

  class Calc2 extends Calc {
    override def run = 0
  }

  val c1 = new Calc1().run                        //> c1  : Int = 1
  val c2 = new Calc2().run                        //> c2  : Int = 0
}

这是Scala特征的使用方式吗?

2 个答案:

答案 0 :(得分:1)

是的,这是您可以在Scala中使用特征的一种方法。

但与Java不同,Scala特征也可以包含一些(可能是默认的)实现。

他们在Scala中是一个复杂的野兽;我建议仔细阅读它们的用法。

答案 1 :(得分:1)

这个例子对我来说似乎没问题。几句话:

1)如果你有不改变的特质成员,可以考虑将它们声明为lazy val。 Lazy vals只被评估一次(第一次需要它们时),另一方面,def s每次被调用时都会被评估。

2)如果您想阻止其他类继承您的特征,请考虑将其声明为sealed trait。这意味着只接受在同一文件中声明的子类。

3)您不需要空括号来实例化Scala中的类。

4)Scala特性与Java接口最重要的区别在于它们也可以包含方法的实现,而不仅仅是声明它们。 (再次问好,多重继承:))

考虑到这一切,我们可以通过以下方式重写您的特定示例:

package main.scala

object traitsfun {
  println("Welcome to the Scala worksheet")       //> Welcome to the Scala worksheet

  sealed trait Calc {
    lazy val run: Int = 0 // val should have a default value
    def standardMethod(param:String) = println(s"Hello $param")
  }

  class Calc1 extends Calc {
    override lazy val run = 1
  }

  class Calc2 extends Calc {
    override lazy val run = 0
  }

  val c1 = (new Calc1).run                        //> c1  : Int = 1
  val c2 = (new Calc2).run                        //> c2  : Int = 0
  (new Calc1).standardMethod("Calc1")             //> "Hello Calc1"
}

(当然,所有这些只是用非常基本的例子来表达:))