[SCALA] 자바에서 구현 방법과 스칼라 특성을 사용하여
SCALA자바에서 구현 방법과 스칼라 특성을 사용하여
나는 자바에서 스칼라의 특성에 구현 된 메소드를 호출 할 수 없습니다, 또는 방법이 됐을까?
내가 스칼라에 있다고 가정 해 봅시다 :
trait Trait {
def bar = {}
}
자바에서 나는로 사용하는 경우
class Foo implements Trait {
}
자바는 그 형질이 추상적없는 불평과 형질의 추상 메소드 바 ()를 오버라이드 (override)하지 않습니다
해결법
-
==============================
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.줄이 빈 단위 (NOP의 종류를) 반환되기 때문에 그것은 참 추상적 아니다. 시험:
줄이 빈 단위 (NOP의 종류를) 반환되기 때문에 그것은 참 추상적 아니다. 시험:
trait Trait { def bar: Unit }
그 다음 줄은 무효 반환 자바 추상적 인 방법이 될 것입니다.
from https://stackoverflow.com/questions/7637752/using-scala-traits-with-implemented-methods-in-java by cc-by-sa and MIT license
'SCALA' 카테고리의 다른 글
[SCALA] 어떻게 구조화 스트리밍을 사용 카프카에서 JSON 형식의 기록을 읽어? (0) | 2019.11.01 |
---|---|
[SCALA] 스칼라 : mapValues이보기를 생산하고 안정적인 대안이 왜? (0) | 2019.11.01 |
[SCALA] 스칼라 : 객체 목록에서 중복 제거 (0) | 2019.11.01 |
[SCALA] 스칼라의 방법 대 기능 (0) | 2019.11.01 |
[SCALA] 왜 스칼라에서 패턴 매칭이되지 변수와 함께 작동합니까? (0) | 2019.11.01 |