2010-04-28 4 views
3

나는 같은 몇 가지 특성이있는 경우 :특성 구현

trait A {...} 
trait B extends A{...} 
trait C1 extends B{...} 
trait C2 extends A{...} 

나는 두 가지 방법 (C1과 C2는 같은 기능을 추가)

class Concrete1 extends B with C1 
class Concrete2 extends B with C2 

어떤 변형이 더 나은 (효율적인)입니다에서 클래스를 작성 할 수 있습니까?

+1

C1과 C2가 동일한 기능을 추가하는 이유는 무엇입니까? – RoToRa

+0

메서드 호출에 대한 런타임 효율성? 프로그래머의 가독성을위한 효율성? 메소드 호출에 대한 –

+0

@Mitch 블레 빈스 런타임 효율 (내가 콘크리트에 대해 생각하고는 {1,2} 인스턴스화 시간) 상속에 @Difference은 - 어떤것는 다른 클래스를 확장하지만, 같은 F 기능이 – Jeriho

답변

4

그들은 성능면에서 동일하다. 이 같은 테스트를 작성하는 경우 : 당신은 그때 가서 C1C2의 초기화를 보면 당신은

public Traits$Dessert(); 
    Code: 
    0: aload_0 
    1: invokespecial #29; //Method java/lang/Object."<init>":()V 
    4: aload_0 
    5: invokestatic #33; //Method Traits$A$class.$init$:(LTraits$A;)V 
    8: aload_0 
    9: invokestatic #36; //Method Traits$B$class.$init$:(LTraits$B;)V 
    12: aload_0 
    13: invokestatic #39; //Method Traits$C1$class.$init$:(LTraits$C1;)V 
    16: return 

public Traits$Salad(); 
    Code: 
    0: aload_0 
    1: invokespecial #29; //Method java/lang/Object."<init>":()V 
    4: aload_0 
    5: invokestatic #33; //Method Traits$A$class.$init$:(LTraits$A;)V 
    8: aload_0 
    9: invokestatic #36; //Method Traits$B$class.$init$:(LTraits$B;)V 
    12: aload_0 
    13: invokestatic #39; //Method Traits$C2$class.$init$:(LTraits$C2;)V 
    16: return 

를 참조 Salad

object Traits { 
    trait A { def a = "apple" } 
    trait B extends A { def b = "blueberry" } 
    trait C1 extends B { def c = "cherry" } 
    trait C2 extends A { def c = "chard" } 
    class Dessert extends B with C1 { } 
    class Salad extends B with C2 { } 
} 

Dessert에 대한 바이트 코드를보고, 그들이있어 둘 다 비어있다. 당신이 c에 대한 메서드 호출을 보면, 다시, 그것은 하나 C1 또는 C2에 정의 된 하나에 대한 참조입니다.

이 때문에 계층의 특성을 해석하는 방법을 발생합니다. 당신은 스택로 생각할 수 있습니다 때마다 당신이 전체 상속 계층 구조가 무엇이든 이미 거기에 다시 추가되지 않습니다 것을 제외하고 스택 으로 푸시됩니다 "로"를 추가합니다. 그래서 B를 확장하기 때문에 클래스 Salad 이미 B을 집어 이후 C2B 여부가 있는지 여부를 중요하지 않습니다.