Преобразование из интерфейсов в черты

1

Вот пример того, как я использовал интерфейсы 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
    Строго не обязательно включать ключевое слово «override», когда признак не обеспечивает реализацию значения или функции по умолчанию в своем контракте.
  • 0
    ... но это приятно.
Теги:

2 ответа

1
Лучший ответ

Мне кажется, что это пример. Несколько замечаний:

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"
}

(Конечно, все это просто царапает поверхность самым простым примером :))

1

Да, это один из способов использования черт в Scala.

Но в отличие от Java, свойства Scala также могут содержать биты (возможно, по умолчанию) реализации.

Они - сложный зверь в Скале; Я предлагаю прочитать подробное объяснение их использования.

  • 0
    Вы смотрели на методы по умолчанию на интерфейсах в Java 8 ? Вы по-прежнему не можете добавлять поля в интерфейсы Java, но вы можете предоставить реализации для методов. Черты Scala все еще более гибкие, так как они в основном просто абстрактные классы с конструктором с 0 аргументами.
  • 0
    Я предполагал Java 7.

Ещё вопросы

Сообщество Overcoder
Наверх
Меню