如何建模和实现可能从不同类继承的类?

时间:2015-07-20 12:52:24

标签: python-2.7 inheritance class-diagram

我有以下'实体'在我的模型中:DataItemStringIntegerArgument。 我不确定如何创建一个反映以下方面的类图:

  • StringDataItem
  • IntegerDataItem
  • Argument可以是StringIntegerDataItem(即String也不Integer}。

我是否必须创建其他类" StringArgument"," IntegerArgument"和" DataItemArgument"还是有更好的解决方案?我假设从StringIntegerDataItem继承Argument不是一个好的解决方案,对吗?

一般情况下:我如何为一个类从一个类或另一个类继承的案例建模?

PS:实现将在Python 2.7中,但我对一般问题感兴趣,所以任何引用其他语言的解决方案都可以。

2 个答案:

答案 0 :(得分:1)

在我看来,你的通用类是Argument,而你的其他三个类应该继承它。

这确实需要StringInteger的包装类。

你的问题让我想起了复合设计模式,但我不确定它是否是你想要的。

答案 1 :(得分:1)

一种方法是将Argument概念与数据项的概念分开。您StringInteger都是DataItem,这是对的,但我不相信ArgumentDataItem 。它只有一个。这自然导致:

    DataItem
     ^    ^
    /      \
   |       |
String    Integer

并且Argument会将指针或引用(或实现语言支持的任何内容)保存到DataItem。参数可能不仅包含(一个)数据(项目);例如,如果它是程序的命令行参数,您可能希望保留位置信息。因此,对我来说,参数包含数据,而不是参数 数据。

class Argument {
  public:
    // etc
  private:
    DataItem* data;
};

(请注意,这种方法可以在大多数支持面向对象编程的语言中实现。)

您可以将StringArgumentIntegerArgument作为单独的类型,保留相关类型的成员,但这样做的相关性将根据情况和实现语言而有所不同(例如,在Python中) ,你不会关心它是Integer还是String,只要它订阅DataItem规定的接口即可。在C ++中,您可以使用模板将Argument类作为通用容器提供:

template <typename data_type>
class Argument {
  public:
    // etc.
  private:
   data_type data;
};

typedef Argument<String> StringArgument; // "composes a" String
typedef Argument<Integer> IntegerArgument; // "composes an" Integer

换句话说,确切地说,如何实现这一点将取决于您选择的语言提供的设施,但如果您不认为参数是&#34;一种&#34;设计更简单;数据,而不是数据的容器(或持有者)&#34;。

作为另一个例子,再次在C ++中,您可以从相关数据类型继承Argument类型...

template <typename data_type>
class Argument : public data_type {
  // etc.
};

typedef Argument<String> StringArgument; // "is a" String
typedef Argument<Integer> IntegerArgument; // "is an" Integer

(请注意,这种方法需要一种语言来支持泛型编程,在某种意义上类似于C ++模板)。

这可以追溯到数据的概念,而不是包含数据。