Вот пример того, как я использовал интерфейсы 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?
Мне кажется, что это пример. Несколько замечаний:
1) если у вас есть признаки, которые не меняются, подумайте об объявлении их как lazy val
s. 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"
}
(Конечно, все это просто царапает поверхность самым простым примером :))
Да, это один из способов использования черт в Scala.
Но в отличие от Java, свойства Scala также могут содержать биты (возможно, по умолчанию) реализации.
Они - сложный зверь в Скале; Я предлагаю прочитать подробное объяснение их использования.