当前位置 : 主页 > 手机开发 > 其它 >

继承 – 以非耦合方式向类添加功能

来源:互联网 收集:自由互联 发布时间:2021-06-19
我写了一个名为Container的类来处理层次结构(对类用户可见)并将它们内部转换为平面数组.因此,对于Container的外部,它看起来像Container的层次结构,每个容器都有父节点和子节点. 我希望将
我写了一个名为Container的类来处理层次结构(对类用户可见)并将它们内部转换为平面数组.因此,对于Container的外部,它看起来像Container的层次结构,每个容器都有父节点和子节点.

我希望将此功能添加到某些类中.例如Widget类,它必须具有Container定义的相同功能.

我可以让Widget从Container继承.现在,Container被定义为具有this(),数据成员,成员函数,不变量和单元测试的类.容器包含一个容器数组,因此设计中有一个错误:如果Foobar还继承了Container并且我们将Foobar项添加到Widget的容器​​中怎么办?这一定是被禁止的.它们共享相同的基类,但它们具有不同目的的根本不同的东西……它们似乎只是共享一些功能.

将Container定义为接口是不可能的,因为它包含数据成员(并且不能解决问题).将Container定义为mixin,因为我们也有this()功能(或者这将如何解决?). mixin中函数的可见性属性也不起作用.另外,我无法传递Widget类的这个参数,因为它需要是平面数组的第一个元素.

我想给Container一个模板参数,告诉它它是什么容器:

abstract class Container(T)
{
    ...

    T[] elements;
}

class Widget: Container!Widget
{
}

这给出了一个错误:类容器.__ unittest2.Widget基类由Container正向引用.

你会如何实现这个?我还可以在Container中添加检查,以确保在添加子项时,它与父项具有相同的类型.但我该如何检查呢?

abstract class Container
{
    void add(Container child)
    {
        // pseudo-code
        assert (is(getFirstDerivedType(this) == getFirstDerivedType(child))); 

        ...
    }

    ...

    Container[] elements;
}

编辑:
即使第一段代码没有发出错误信号,它仍然无法真正解决问题.我不能随意添加更多功能,因为只允许一个基类.其他人需要是接口,这是根本不同的东西.接口确保派生类中存在某些功能,它们本身不添加功能.

这应该用(模板)mixins来解决.但是mixins不能向构造函数添加代码(只有在未定义时才替换),不能将代码添加到不变量(不定义多次定义),不能指定成员函数可见性或使用其他类/结构特定关键字…

我认为你这是错误的方式.您正试图从内部向各种类添加功能,而从外部添加它会更有意义,即扩展它们.

容器应该包含Widget,而不是相反.然后,您可以使用别名将非容器调用转发到包含的Widget.

像这样的东西:

import std.stdio;

class Container(T)
{
public:
    this(T elem) { m_this = elem; add(this); }
    void add(Container elem) { m_elems ~= elem; }

    alias m_this this;

private:
    T m_this;
    Container m_elems[];
}

class Widget
{
public:
    this(int x) { this.m_x = x; }
    int foo() { return m_x; }
    int m_x;
}

alias Container!Widget CWidget;

void main()
{
    CWidget w1 = new CWidget(new Widget(1));
    CWidget w2 = new CWidget(new Widget(2));

    w1.add(w2);
    writeln(w1.m_x);
    writeln(w1.foo());
}

注意你如何通过调用w1.m_x和w1.foo()仍然可以像使用Widget一样使用w1.

网友评论