scala – 是否添加了一个具有实现破坏向后兼容性的特征方法?
在将具有默认实现的方法添加到特征时,我对后向兼容性感到困惑.喜欢:
以前的版本 trait Foo 新版本 trait Foo { def verifyConsistency: Option[String] = ??? // provide default implementation } Migration Manager报告此添加为二进制不兼容.那是对的吗? 解决方法
是的,这是正确的.
当您定义特征Foo时,它将在底层创建一个(JVM)接口Foo和一个(JVM)类Foo $类,其中所有方法实现都定义为静态方法.相应的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对象模型不支持多重继承. traits实现不能简单地放在你可以扩展的类中,因为你只能在JVM上扩展一个类. 这种情况的消失是,每当具体类混合一个特征时,该类为特征的每个成员定义“存根”方法(这些方法简单地转发到实际的实现,这是一个静态方法). 一个结果是,如果向特征添加新方法,即使您定义了一个实现,也是不够的:混合特征的具体类需要重新编译(以便将新方法的存根添加到类中) .如果你不重新编译这些类,那么你的程序将无法运行,因为你现在有一个被认为具体的类(非抽象)并扩展相应的接口但实际上错过了新方法的实现. 在您的情况下,这意味着具有扩展接口Foo但没有任何verifyConsistency实现的具体类. 因此二进制不兼容. (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |