(참고 : 명백한 이유로 제목에서 '문제'대신 '오류'를 사용했습니다 ..;)).
Scala의 Traits에 대한 기본적인 내용을 읽었습니다. Java 또는 C #의 인터페이스와 유사하지만 메소드의 기본 구현을 허용합니다.
궁금한 점이 있는데, 이것이 "다이아몬드 문제"의 원인이 될 수없는 이유입니다. 이것이 많은 언어가 다중 상속을 먼저 피하는 이유입니다.
그렇다면 스칼라는 이것을 어떻게 처리합니까?
(참고 : 명백한 이유로 제목에서 '문제'대신 '오류'를 사용했습니다 ..;)).
Scala의 Traits에 대한 기본적인 내용을 읽었습니다. Java 또는 C #의 인터페이스와 유사하지만 메소드의 기본 구현을 허용합니다.
궁금한 점이 있는데, 이것이 "다이아몬드 문제"의 원인이 될 수없는 이유입니다. 이것이 많은 언어가 다중 상속을 먼저 피하는 이유입니다.
그렇다면 스칼라는 이것을 어떻게 처리합니까?
답변:
다이아몬드 문제는 선택할 방법의 구현을 결정할 수 없다는 것입니다. Scala는 언어 사양의 일부로 선택할 구현을 정의하여이 문제를 해결합니다 ( 이 Wikipedia 기사에서 Scala에 대한 부분 읽기 ).
물론, 동일한 순서 정의가 클래스 다중 상속에서도 사용될 수 있습니다. 왜 특성에 귀찮습니까?
IMO가 생성자 인 이유. 생성자는 일반 메소드가 가지고 있지 않은 몇 가지 제한 사항이 있습니다-객체마다 한 번만 호출 할 수 있으며 각 새 객체에 대해 호출해야하며 하위 클래스 생성자는 첫 번째 명령이므로 부모의 생성자를 호출해야합니다 (대부분의 언어는 매개 변수를 전달할 필요가 없으면 암시 적으로 수행하십시오).
B와 C가 A와 D를 상속하고 B와 C의 생성자가 모두 A의 생성자를 호출하면 D의 생성자는 A의 생성자를 두 번 호출합니다. 스칼라처럼 때문에 방법이 여기에 작동하지 않습니다를 선택할 수있는 구현 정의 모두 B의와 C의 생성자를 호출해야합니다.
특성은 생성자가 없기 때문에이 문제를 피합니다.
스칼라는 "특성 선형화 (trait linearization)"로 다이아몬드 문제를 피합니다. 기본적으로 오른쪽에서 왼쪽으로 확장하는 특성에서 메소드 구현을 찾습니다. 간단한 예 :
trait Base {
def op: String
}
trait Foo extends Base {
override def op = "foo"
}
trait Bar extends Base {
override def op = "bar"
}
class A extends Foo with Bar
class B extends Bar with Foo
(new A).op
// res0: String = bar
(new B).op
// res1: String = foo
그러나, 특성 목록에는 다른 특성을 확장 할 수 있으므로 명시 적으로 제공 한 특성 목록이 포함되어있을 수 있습니다. 자세한 설명은 다음과 같습니다. 스택 가능한 수정으로서의 특성과 여기에 선형화의보다 완전한 예 : 다중 상속이 아닌 이유는 무엇입니까?
다른 프로그래밍 언어에서는이 동작을 "메소드 해결 순서"또는 "MRO"라고도합니다.