Java에서 구현 된 메서드와 함께 Scala 특성 사용
Java에서 Scala 특성으로 구현 된 메서드를 호출 할 수 있다고 생각합니다. 아니면 어디입니까?
Scala에 안전한 가정합니다.
trait Trait {
def bar = {}
}
그리고 Java로 사용하면
class Foo implements Trait {
}
자바는 다음과 같이 불평합니다. Trait is not abstract and does not override abstract method bar() in Trait
대답
자바에서 관점 인터페이스Trait.scala
로 컴파일됩니다 . 따라서 Java에서는 구현하는 해석되어 오류 메시지를 분명히 만듭니다. 짧은 대답 : Java (!)에서 다중 상속을 가능하게 Java에서 특성 구현을 사용할 수 없습니다.Trait
Trait
Scala에서 어떻게 구현 검증?
긴 대답 : 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
인터페이스입니다- abstract
Trait$class
(혼동하지 않고Trait.class
) 클래스는 기술적으로 인터페이스를 구현 하지 않는 투명하게 생성Trait
합니다. 그러나 인스턴스를 인수로static bar()
취하는 메소드 가 있습니다Trait
(일종의this
) Foo
Trait
인터페이스 구현scalac
Trait
에 의해 방법을 자동으로 구현 합니다Trait$class
. 이것은 본질적으로Trait$class.bar(this)
.
참고 Trait$class
둘의 구성원하지 Foo
않는 Foo
것 확장 할 수 있습니다. 전달하여 전달합니다 this
.
여러 특성의 혼합
Scala의 작동 방식에 대한 논의를 계속해서 ... 여러 가지 특성을 혼합하는 것이 아래에서 어떻게 작동하는지 상상하기.
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
확장 인터페이스가 될 것 Trait
입니다. 이제 Trait2
정의 할 때 마지막으로 오면 Foo
:
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"
}
다음은 유용에 대한 새로운 'Foo'입니다.
class FooOnSteroids extends Foo with Trait1 with Trait2
다음과 같이 번역됩니다.
특성 1
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";
}
}
특성 2
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";
}
}
FooOnSteroids
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);
}
}
따라서 전체 스택 호출은 다음과 가변합니다.
- FooOnSteroids 인스턴스 (진입 점)의 'bar'메서드
- Trait2 $ class의 'bar'정적 메서드는 이것을 인수로 전달하고 'Trait2 $$ super $ bar ()'메서드 호출과 문자열 ", Trait2"의 연결을 반환합니다.
- ...를 호출하는 FooOnSteroids 인스턴스의 'Trait2 $$ super $ bar ()'
- Trait1 $ class의 'bar'정적 메서드는 이것을 인수로 전달하고 'Trait1 $$ super $ bar ()'메서드 호출과 문자열 ", Trait1"의 연결을 반환합니다.
- 호출하는 FooOnSteroids 인스턴스의 'Trait1 $$ super $ bar'...
- 원래 Foo의 'bar'방법
결과는 "Foo, Trait1, Trait2"입니다.
결론
모든 것을 읽었다면 원래 질문에 대한 답은 처음 네 줄에 있습니다.
bar
빈 Unit
(일종의 NOP)을 반환하기 때문에 실제로 추상 이 아닙니다 . 시험:
trait Trait {
def bar: Unit
}
그런 다음 bar
을 반환하는 Java 추상 메서드가 void
됩니다.
참고 URL : https://stackoverflow.com/questions/7637752/using-scala-traits-with-implemented-methods-in-java
'ProgramingTip' 카테고리의 다른 글
F #은 어떤 영역에서 "사용에있어 전혀 의미가 없습니까?" (0) | 2020.12.07 |
---|---|
주요 getoutput () 하위 프로세스에서 해당 (0) | 2020.12.07 |
Bash에서 함수 정의를 인쇄하는 방법은 무엇입니까? (0) | 2020.12.07 |
file_put_contents () 실행시 폴더 생성 (0) | 2020.12.07 |
ng-repeat : 객체 배열의 각에 대한 액세스 키 및 값 (0) | 2020.12.07 |