开发者

subtyping relationships in OO paradigm

开发者 https://www.devze.com 2023-03-31 03:30 出处:网络
Let us consider a class \'Human\' -->(1..*) \'Human\' , where Human is a supertype. Say it has subclasses like \'Male\', \'Female\', \'SociallyPathologicalMale\' etc. The basic association b/w 2 entit

Let us consider a class 'Human' -->(1..*) 'Human' , where Human is a supertype. Say it has subclasses like 'Male', 'Female', 'SociallyPathologicalMale' etc. The basic association b/w 2 entities remains common, the subtypes define name and constraints on the association but the basic relationship is still m:n b/w 2 Human entities. Example:-

  • 'Male' -->(1:1)('wife'(relationship name)) 'Female'

  • 'Female'-->(1:1)('husband') 'Male'

  • 'SociallyPathologicalMale'-->(1:0)('friends') 'Male'

    [edit 13/12/2011] - If say we have to implement it in java, what are some of the best practices such that reuse of the association possible?

Say we start with base class :-

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

something like

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

Now the fact that relationships field is redefined in Man (or any other subclass) could be structurally enforceable , i.e while defining any subclass it should be mandatory for me to define out the relations开发者_开发百科hips. Is it possible for such a kind of construct in java ?? are there other languages that can do this easily ??


Two methods of implementation i would use would be Inheritance and Composition.

The is a relationship is expressed with inheritance and has a relationship is expressed with composition.

Both inheritance and composition allow you to place sub-objects inside your new class. Two of the main techniques for code reuse are class inheritance and object composition.

Inheritance

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

Composition

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


There are two important things you should review from your scenario:

1) Fields cannot be redefined by subclasses. It is not a limitation of the language (Java) but a conceptual imposition that is reasonable. Fields define what an object is and methods define what an object does and how. The only thing you can redefine is how things are done by your objects but you are not allowed to change what your superclass is or does. (I'm saying "objects" but please keep in mind that I mean "the instances of the class" since you actually define the behavior in the class body).

2) You must make the Relationship a first-class object. Since it is not enough using what the paradigm provides you: "is a" and "has a". As Darren Burgess stated, the paradigm provides you with two conceptual relationships: "is a" and "has a". For the Human->Man or Human->Woman example, you can use inheritance, in other words, "is a". The Man class extends Human because a Man is a Human. The difficulty is on the "has a" relationship since OOP does not allows you to specify cardinality and you also want to specify a name on the relationship. For simplicity, let's define relationships as binary. For example, A man has a Wife or a Woman has a Husband. For the relationship John is the father of Tom and Linda, we will define two relationships: John is the father of Tom and John is the father of Linda. The problem with your approach is that you specified a List of Man and a List of Woman. However, what a Human actually has is a Collection of Relationships. The design will look like this:

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".
}

Party and counterparty are the members of the relationship and the object instance of Relationship will represent how one relates to the other.

Defining particular behavior would be more ad-hor. For example, a SociallyPathologicalMale will not have any Relationship. You can add the following method to Human:

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

The SociallyPathologicalMale class (who extends Male) will inherit that method and will redefine it as follows:

public void addRelationship(Relationship newRelationship) { // Nothing to do here. }

Basically, as SociallyPathologicalMale, by definition, is unable to have any relationship, you disable programmatically the ability provided by the superclass Male.

I hope it clarifies your question.

0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号