복붙노트

[SCALA] 자바에서 구현 방법과 스칼라 특성을 사용하여

SCALA

자바에서 구현 방법과 스칼라 특성을 사용하여

나는 자바에서 스칼라의 특성에 구현 된 메소드를 호출 할 수 없습니다, 또는 방법이 됐을까?

내가 스칼라에 있다고 가정 해 봅시다 :

trait Trait {
  def bar = {}
}

자바에서 나는로 사용하는 경우

class Foo implements Trait {
}

자바는 그 형질이 추상적없는 불평과 형질의 추상 메소드 바 ()를 오버라이드 (override)하지 않습니다

해결법

  1. ==============================

    1.자바의 관점에서 Trait.scala는 형질 인터페이스로 컴파일됩니다. 귀하의 오류 메시지가 분명하게 - 따라서 자바에서 구현 형질는 인터페이스를 구현하는 것으로 해석된다. 짧은 답변 :이 자바에서 다중 상속을 가능하게 때문에 당신은 자바의 특성 구현을 활용할 수 없다 (!)

    자바의 관점에서 Trait.scala는 형질 인터페이스로 컴파일됩니다. 귀하의 오류 메시지가 분명하게 - 따라서 자바에서 구현 형질는 인터페이스를 구현하는 것으로 해석된다. 짧은 답변 :이 자바에서 다중 상속을 가능하게 때문에 당신은 자바의 특성 구현을 활용할 수 없다 (!)

    긴 대답 : 그래서 어떻게 스칼라에서 작동합니까? 하나는 다음과 같은 코드를 찾을 수 있습니다 생성 된 바이트 코드 / 클래스를 보면 :

    interface Trait {
        void bar();
    }
    
    abstract class Trait$class {
        public static void bar(Trait thiz) {/*trait implementation*/}
    }
    
    class Foo implements Trait {
        public void bar() {
            Trait$class.bar(this);  //works because `this` implements Trait
        }
    }
    

    그 형질 $ 클래스는 없다 둘 푸의 구성원이나 푸 그것을 확장 않습니다. 이를 전달하여 그것에 그것은 단순히 위임한다.

    스칼라가 어떻게 작동하는지 ... 여러 특성에 혼합하는 것은 아래의 작동 방식을 상상하기 쉽다 말했다되고 그건에 대한 여담을 계속하려면 :

    trait Trait1 {def ping(){}};
    trait Trait2 {def pong(){}};
    class Foo extends Trait1 with Trait2
    

    로 변환 :

    class Foo implements Trait1, Trait2 {
      public void ping() {
        Trait1$class.ping(this);    //works because `this` implements Trait1
      }
    
      public void pong() {
        Trait2$class.pong(this);    //works because `this` implements Trait2
      }
    }
    

    지금은 같은 방법을 재정의하는 여러 특성에 혼합하는 방법을 쉽게 상상할 수 :

    trait Trait {def bar(){}};
    trait Trait1 extends Trait {override def bar(){}};
    trait Trait2 extends Trait {override def bar(){}};
    

    다시 Trait1 및 Trait2는 형질 연장 인터페이스 될 것이다. 푸를 정의 할 때 이제 Trait2 지난 오면 :

    class Foo extends Trait1 with Trait2
    

    당신은 얻을 것이다:

    class Foo implements Trait1, Trait2 {
        public void bar() {
            Trait2$class.bar(this); //works because `this` implements Trait2
        }
    }
    

    그러나 Trait1 및 Trait2는 (마지막으로 Trait1 제조) 전환 될 것이다 :

    class Foo implements Trait2, Trait1 {
        public void bar() {
            Trait1$class.bar(this); //works because `this` implements Trait1
        }
    }
    

    스택 수정 작업으로 이제 어떻게 특성을 고려하십시오. 정말 유용한 클래스 푸를 상상해 :

    class Foo {
      def bar = "Foo"
    }
    

    어떤이는 특성을 사용하여 몇 가지 새로운 기능을 풍부하게 할 :

    trait Trait1 extends Foo {
      abstract override def bar = super.bar + ", Trait1"
    }
    
    trait Trait2 extends Foo {
      abstract override def bar = super.bar + ", Trait2"
    }
    

    여기에 스테로이드에 새로운 '푸'는 것입니다 :

    class FooOnSteroids extends Foo with Trait1 with Trait2
    

    그것은에 번역 :

    interface Trait1 {
      String Trait1$$super$bar();
      String bar();
    }
    abstract class Trait1$class {
      public static String bar(Trait1 thiz) {
        // interface call Trait1$$super$bar() is possible
        // since FooOnSteroids implements Trait1 (see below)
        return thiz.Trait1$$super$bar() + ", Trait1";
      }
    }
    
    public interface Trait2 {
      String Trait2$$super$bar();
      String bar();
    }
    public abstract class Trait2$class {
      public static String bar(Trait2 thiz) {
        // interface call Trait2$$super$bar() is possible
        // since FooOnSteroids implements Trait2 (see below)
        return thiz.Trait2$$super$bar() + ", Trait2";
      }
    }
    
    class FooOnSteroids extends Foo implements Trait1, Trait2 {
      public final String Trait1$$super$bar() {
        // call superclass 'bar' method version
        return Foo.bar();
      }
    
      public final String Trait2$$super$bar() {
        return Trait1$class.bar(this);
      }
    
      public String bar() {
        return Trait2$class.bar(this);
      }      
    }
    

    다음과 같이 그래서 전체 스택 호출은 다음과 같습니다 :

    그리고 결과는 "푸, Trait1, Trait2"입니다.

    당신이 모든 것을 읽을 관리 한 경우, 원래의 질문에 대한 답변은 처음 네 줄은 ...

  2. ==============================

    2.줄이 빈 단위 (NOP의 종류를) 반환되기 때문에 그것은 참 추상적 아니다. 시험:

    줄이 빈 단위 (NOP의 종류를) 반환되기 때문에 그것은 참 추상적 아니다. 시험:

    trait Trait {
      def bar: Unit
    }
    

    그 다음 줄은 무효 반환 자바 추상적 인 방법이 될 것입니다.

  3. from https://stackoverflow.com/questions/7637752/using-scala-traits-with-implemented-methods-in-java by cc-by-sa and MIT license