2011-12-31 114 views
5

我处于需要混合另一个包中定义的特征的情况。为了帮助进行测试,此特征中的受保护方法是包合格的。下面是一个例子:由不同包中的类继承受程序包保护的方法

package A { 
    trait X { 
    protected[A] def method(arg: Int) 
    } 
} 

package B { 
    class Y extends A.X { 
    protected[A] def method(arg: Int) { } 
    } 
} 

与scalac编译此2.9.1收率:

test.scala:9: error: A is not an enclosing class 
    protected[A] def method(arg: Int) { } 

“被保护的[A]” 在Y类更改为在此任何其他访问修饰符的结果:

test.scala:9: error: overriding method method in trait X of type (arg: Int)Unit; 
method method has weaker access privileges; it should be at least protected[A] 
    override protected def method(arg: Int) { } 

我的问题是这样的:假设特质X的定义不能改变,是否有任何改变Y类,这将允许它扩展特质X? (同时保留一定程度的“受保护”访问)

如果这不可行,是否还有其他推荐的设计策略可以解决此问题? (除了使'方法'公开)

+0

我应该补充一点,我试图回答这个设计是否不可能的简单问题,例如修复的唯一(简单)方法是将'protected [A]'更改为'public'。它只是看起来像一个子类,不管包应该能够访问?或不? – nu11ptr 2011-12-31 19:18:23

+0

看起来像'正确'的解决方案是将Y类的定义分解成一个类和一个特征。我将把这个特质放在A的一个子包中,在那里定义'方法',然后将它与Y类混合。在现实世界中,A是'marketdata',B是'broker',所以它是有意义的当我们最终有一个代理实例也是一个数据提供者来分解这个功能时,将它放在一个子数据包marketdata中,然后混合进来。这可能是一个更好的设计,因为它们是两个完全不同的问题(订单处理与市场数据)。 – nu11ptr 2012-01-02 03:27:02

回答

2

我最终用适配器解决了这个问题。尽管我无法更改原始特征,但我可以在同一个包中添加另一个特征(但出于其他原因,将Y类放在该包中是没有意义的)。 Y类中的'adapterMethod'有资格将B包装为一个实验,但很可能这对我的用例来说是不必要的。以下编译为斯卡拉2.9.1:

package A { 
    trait X { 
    protected[A] def method(arg: Int) 
    } 

    trait PackageAdapter { 
    protected[A] def method(arg: Int) { adapterMethod(arg) } 

    protected def adapterMethod(arg: Int) 
    } 
} 

package B { 
    class Y extends A.X with A.PackageAdapter { 
    protected[B] def adapterMethod(arg: Int) { } 
    } 
} 

我对这个解决方案并不是疯狂的,但它并没有那么糟糕。 Y类是一个例外情况,因为使用特征X的其余类在A包中(因为许多其他原因,Y类必须在包B中)。任何更好的想法?

+0

你可以从A得出B:“包A.B {Y类......”? – TechNeilogy 2012-01-01 14:44:51

+0

从技术上来说,是的,但是由于A和B彼此没有任何关系,并且每个都有很多类,所以它会是任意的并且是错误的。 (还是)感谢你的建议。 – nu11ptr 2012-01-02 03:24:39

+0

更新:事实证明,我将通过在两个插件之间拆分Y类来做类似的事情。 – nu11ptr 2012-01-02 03:31:09

相关问题