Inheritance

I have a Party which can be either a Person or a Company.

Implemented with inheritance Party is the super class and
Person and Company the subclasses.

What to do if I want both the Company and the Person
to be able to play the roles of Customer or Partner
under different circumstances and I don't want to duplicate
information or code

Examples:

Party A, a Company in the role of Partner
sells an order to
Party B, a Person in the role of Customer

At a later stage
Party B, a Person in the role of Partner
sells an order to
Party C, a Person in the role of Customer

and even later
Party B, a Person in the role of Partner
sells an order to
Party D, a Company in the role of Customer

In these examples Party B should be able to be both
Customer and Partner depending on context. This should
of course be true for all Partys.

Any ideas of how to do this in an intelligent way

Thank you. Stig Benning



Answer this question

Inheritance

  • vijay prajapati

    dampbarn wrote:

    Now I have checked it out, and this is exactely what I need. I still keep the inheritance <Person : Party> and <Company : Party> but - as you suggest - I let the Party class implement ICustomer and IPartner and use an enum { partner, customer } in Party as well. This solves the problem elegantly. Thanks again.

    dampbarn

    That's sounds too complicated. You only need one class and two interfaces, then implement the interfaces explicitly:

    public interface IPerson
    {
    string PersonMethod();
    }

    public class Party : IPerson
    {
    public string PartyMethod()
    {
    return "This is the party method";
    }

    #region IPerson Members

    string IPerson.PersonMethod()
    {
    return "THis is the person method";
    }

    #endregion

    }

    Then you can create the class and use it through the interfaces:

    Party party = new Party();

    ((IPerson)party).PersonMethod();

    But if you try to access the PersonMethod without the cast to IPerson, like this:
    party.PersonMethod();

    then the compiler will throw an error.

    You do the same with the ICustomer:
    public class Party : IPerson, ICustomer

    //...

    string ICustomer.CustomerMethod()
    {
    return "This is the customer method";
    }

    And you can now only get to the CustomerMethod on the party instance by casting it to ICustomer.

    Putting an enum in a base class to show what type of derived class it is is a bad smell. Whenever I see enums relating to derived types, I know the design could be better.

    Herbie


  • patria

     

    Well, instead of implementing this using class inheritance, could you implement it with interfaces

    Essentially, your Party class would expose the IPerson and ICustomer interfaces.  Then you can simply cast your instance as either one, depending on it's role.

    You may want to ensure that the base class, Party, cannot expose 'Customer' methods except when cast as an ICustomer.  The techniques for this will depend on the language you are using.

     

    Herbie

     


  • Kostas M

    I was afraid you would say so

    Anyway, thanks a lot. You have made me even more thirsty after knowledge and provided very useful suggestions and info.

    dampbarn


  • wendling lionel

    Thank you, this may solve the problem. I will have to experiment though, since I am not too well aquainted with using interfaces - yet! The programming language is C# so using interfaces should pose no problem. I will report how the experiments turns out. Once again thank you.

    dampbarn


  • DavidThi808

    Now I have checked it out, and this is exactely what I need. I still keep the inheritance <Person : Party> and <Company : Party> but - as you suggest - I let the Party class implement ICustomer and IPartner and use an enum { partner, customer } in Party as well. This solves the problem elegantly. Thanks again.

    dampbarn


  • xyzt

    I see what you mean and get the smell :)

    After posting my last message I found out that I didn't need the enum for the customer/partner case. I saw that just casting the Party to the right interface gave access to the function implemented for that interface.

    But the way you implement the interface gives me information I didn't have before. Thanks!

    Could you suggest some good books about OO preferably geared towards C#, and preferably with examples like the ones you have shown here and where the emphasis isn't on inheritance alone and preferably from some seasoned guys that have worked with implementing OO intelligently in real life

    I have read a number of books for OO and C#, but I have for example never seen an interface implemented like you do.

    Thanks again.

    dampbarn


  • eugen_r2

    dampbarn wrote:

    ...


    But the way you implement the interface gives me information I didn't have before. Thanks!

    Could you suggest some good books about OO preferably geared towards C#, and preferably with examples like the ones you have shown here and where the emphasis isn't on inheritance alone and preferably from some seasoned guys that have worked with implementing OO intelligently in real life

    I have read a number of books for OO and C#, but I have for example never seen an interface implemented like you do.

    Thanks again.

    dampbarn

    Unfortunately, I can't recommend a good C# - specific book on OO. All the bits and pieces I know come from experimentation, blog-reading and MSDN trawling . The method I used is called 'explicit interface declarations' (or something close to that). When you add an interface to a class in VS2005, you get a smart tag appearing under the interface name. Clicking this gives two options: 'implicitly implement interface' and 'explicitly implement interface'. In this example you would use 'explicitly implement interface'.

    An implicit interface declaration makes a standard method declaration that happens to match one in an interface. This method will be available through the base class or through the interface.

    An explicit interface declaration 'tags' the method as belonging to the interface and is only accessible through the interface.

    I can't give you much more info than that, so if you want more I'm afraid you'll have to start trawling (or hope that someone more knowledable sees this and gives a full response).

    Herbie


  • Inheritance