OO范式中的子类型关系

时间:2011-08-26 09:57:57

标签: data-modeling object-oriented-analysis

让我们考虑一个类'人' - >(1 .. *)'人',其中人类是超类型。假设它有子类,如'男性','女性','SociallyPathologicalMale'等。基本关联b / w 2实体仍然很常见,子类型定义关联的名称和约束但基本关系仍然是m:nb / w 2人类实体。 例如: -

  • '男' - >(1:1)('妻子'(关系姓名))'女'

  • '女性' - >(1:1)('丈夫')'男'

  • 'SociallyPathologicalMale' - >(1:0)('朋友')'男'

    [edit 13/12/2011] - 如果说我们必须在java中实现它,那么有哪些最佳实践可以重用关联?

假设我们从基类开始: -

 class Human{
  private List<Human> relationships; // in a subclass this field, could 
//  this generically be represented ?? 
}

类似

   class Man extends Human{
    private List<Woman> relationships;//should be 0 or 1
    }

现在关系字段在Man(或任何其他子类)中重新定义的事实可以在结构上强制执行,即在定义任何子类时,我必须强制定义关系。 java中有这样一种构造吗?还有其他语言可以轻松完成吗?

2 个答案:

答案 0 :(得分:0)

我将使用的两种实现方法是继承和组合。

is a关系用继承表示,has a关系用组合表示。

继承和组合都允许您将子对象放在新类中。代码重用的两个主要技术是类继承和对象组合。

Inheritance

class Human {
//some code
}
class Male extends Human {
//some code
}

Composition

class Male
{
     Wife mrs = new Wife();
}

答案 1 :(得分:0)

您应该从您的方案中检查两件重要事项:

1)子类不能重新定义字段。它不是语言(Java)的限制,而是一种合理的概念强加。字段定义对象 的内容,方法定义对象做什么如何。您唯一可以重新定义的是如何您的对象执行的操作,但不允许您更改超类 的内容。 (我说的是“对象”,但请记住,我的意思是“类的实例”,因为你实际上在类体中定义了行为。)

2)您必须将关系设为第一类对象。因为使用范式为你提供的东西是不够的:“是一个”和“有一个”。正如Darren Burgess所说,这种范式为你提供了两种概念关系:“是一种”,“就是一种”。对于 Human-&gt; Man Human-&gt; Woman 示例,您可以使用继承,换句话说,“is a”。 Man类扩展了Human,因为一个人是人类。困难在于“有一个”关系,因为OOP不允许您指定基数,并且您还想在关系上指定名称。为简单起见,我们将关系定义为二进制。例如,一个男人有妻子女人有丈夫。对于关系 John是Tom和Linda的父亲,我们将定义两个关系: John是Tom的父亲 John是Linda的父亲。你的方法的问题是你指定了一个男人名单和一个女人名单。然而,人类实际拥有的是关系的集合。设计将如下所示:

public Human {
    private Collection<Relationship> relationships;
}

public Relationship {
    private Human party; // We are defining only relationships between humans.
    private Human counterparty;
    private String name; // e.g., "is the Husband of" and "is the Wife of".
}

党和对手方是关系的成员,关系的对象实例将代表一方与另一方的关系。

定义特定行为会更加明显。例如, SociallyPathologicalMale 不会有任何关系。您可以将以下方法添加到人员

public void addRelationship(Relationship newRelationship) {
    relationships.add(newRelationship);
}

SociallyPathologicalMale类(扩展为Male)将继承该方法,并将按如下方式重新定义:

  

public void addRelationship(Relationship newRelationship){       // 在这儿无事可做。 }

基本上,根据定义,SociallyPathologicalMale无法建立任何关系,您可以通过编程方式禁用超类男性提供的功能。

我希望它澄清你的问题。