2013-08-21 30 views

回答

10

嗯是的,它是正确的。

当您定义特征Foo时,它将在全部方法实现中定义为静态方法的同时创建(JVM)接口Foo和(JVM)类Foo$class。相应的Java代码看起来像这样的事情(为您的新的Foo确定指标):

interface Foo { 
    Option<String> verifyConsistency(); 
} 

class Foo$class { 
    static Option<String> verifyConsistency(Foo self) { 
    Predef.???(); 
    } 
} 

当您混合Foo到一个具体的类Bar,JVM级别发生的事情是Bar扩展接口Foo,并通过简单的转发调用Foo$class实现方法verifyConsistency

class Bar implements Foo { 
    Option<String> verifyConsistency() { 
    return Foo$class.verifyConsistency(this); // simple forwarding 
    } 
} 

为什么做这样的原因是JVM对象模型不支持多重继承。特性实现不能简单地放在你可以扩展的类中,因为你只能在JVM上扩展一个类。

这种情况的影响是,每当一个具体类混合一个特质时,该类为特征的每个成员(这些方法简单地转发给实际实现,这是一种静态方法)定义“存根”方法。

其中一个结果是,如果向特征添加新方法,即使定义了实现,也是不够的:混合特征的具体类需要重新编译(以便添加新方法的存根到班级)。如果您不重新编译这些类,那么程序将无法运行,因为您现在将拥有一个类似于具体(非抽象)的类,并且扩展了相应的接口,但实际上错过了新方法的实现。

在你的情况下,这意味着具有扩展接口Foo的具体类,但没有verifyConsistency的任何实现。

因此二进制不兼容。

+1

好的谢谢。我认为整个仪式的特点是你可以添加方法,只要你提供一个默认实现,你不必重新编译所有东西。所以我想我错了:-( –