我可以将可堆叠的特征逻辑移动到父级吗?

时间:2016-09-20 15:06:10

标签: scala traits

我不确定是否可能,或者我在这里提出错误的问题。假设我有类似

的话
trait Parent {
    def foo : String = " Parent "
}

trait Child1 extends Parent {
    override def foo : String = super.foo + " Child 1 "
}

trait Child2 extends Parent {
    override def foo : String = super.foo + " Child 2 "
}

并像

一样使用它
class ChildGroup extends Child1 with Child2
(new ChildGroup).foo

预期结果为" Parent Child 1 Child 2 "

但是我发现很难维护,特别是当其他人使用我的特性而没有像我的意思那样使用它时

trait Child3 extends Parent //<-- not override foo, and no error

trait Child4 extends Parent {
    override def foo : String = " Child 4 " //<-- forget super.foo +
}

并使用

class ChildGroup extends Child1 with Child2 with Child3 with Child4
(new ChildGroup).foo

结果将只是" Child 4 "而我不希望发生这种情况我只是希望它始终是堆栈

所以将堆栈特征的所有逻辑移到Parent

会很好

有可能吗?或者还有其他选择会迫使其他人总是super.foo + x

1 个答案:

答案 0 :(得分:1)

这是面向对象的问题。

您可以将父级定义为:

trait Parent{
    public final def f():String= {
              "Parent" +g();
    }
    protected abstract def g():String
}

trait Child extends Parent{
    def g()= "Child"
}

强制父功能首先在单个孩子之前运行。如果你有多个孩子并且想要在调用一个函数时应用所有这些功能,我认为使用这样的mixin技术是滥用的,这不是这种技术的目的(添加功能)。

如果您想为功能添加功能,请查看 装饰器 设计模式。

问候trait Child3 extends Parent //<-- not override foo, and no error使用reular编码是不可能的。你可以定义宏,但我不建议它,因为它的实验意味着它可以从scala sdk中删除。