将数据成员放在接口中可以吗?

Is it alright to put data members in an interface?

最近,我了解了 composite pattern。我想在我必须实现文件和文件夹 类 的作业中使用它。我意识到像 CFileCfolder 这样的子 类 必须具有相同的属性(namesize)。那我把属性放到interface里可以吗?据我所知,这样做不是好的做法。但是,我不明白为什么我不应该这样做。或者还有其他解决方案吗?

其实不是"is it a good practice"的问题。通过创建一个接口,您正在定义一个标准。问题是,你需要接口的实现来包含那些数据成员吗?您最了解您的实现,因此您确实是唯一可以回答这个问题的人。

作为一般规则,实现接口的 class 应该是一个黑盒子,外界不应该访问任何内部(包括成员数据)。接口定义了支持接口所需的通用功能,我希望这些实现细节仅作为一般规则隐藏在 class 的底层实现中。 YMMV。

我会说这不是问题。区别在于,你有一个 抽象基础 class 而不是 纯接口 class。但是,如果您想保留使用 interface 的灵​​活性来实现不依赖于那些特定成员变量的实现,那么您总是可以创建一个 interface class 以及一个 抽象基础 class 以获得完全的灵活性。虽然这可能很快就会变得过于复杂,但如果需要,您可以随时将 接口 抽象基础 中拆分出来。

using CItemUPtr = std::unique_ptr<class CItem>;

/**
 * Interface class
 */
class CItem
{
public:
    virtual ~CItem() {}

    virtual CItemUPtr findByName(std::string const& name) = 0;
    virtual void setHidden(bool a, bool b) = 0;
};

/**
 * Abstract base class
 */
class AbstractCItem
: public CItem
{
protected:
    std::string name;
    std::size_t size;
};

class CFile
: public AbstractCItem
{
public:

    CItemUPtr findByName(std::string const& name) override
    {
        // stuff
        return {};
    }

    void setHidden(bool a, bool b) override {}
};

class 的设计原则应该是:
'It is impossible to break the class invariant from the outside'
如果构造函数设置 class 不变量,并且所有成员
坚持class不变量,这就实现了。

但是,如果 class 没有 class 不变量,则有
public 成员实现了同样的目标。

// in C++, this is a perfectly fine, first order class
struct Pos
{
    int x,y;
    Pos& operator+=(const Pos&);
};

另见https://en.wikipedia.org/wiki/Class_invariant