CodeGuru Home VC++ / MFC / C++ .NET / C# Visual Basic VB Forums Developer.com
Results 1 to 15 of 24

Hybrid View

  1. #1
    Join Date
    Jul 2008
    Posts
    8

    [RESOLVED] Diamond Inheritance Problem - C#

    This question is specific to C# not providing multiple inheritance unlike C++ and the need to go about using interfaces to implement multiple inheritance.

    It’s about Multiple Inheritance and how to solve diamond Inheritance problem.

    To begin with this is what my class design looks like, on a very high level.

    struct DOB{
    int dd,mm,yy;
    }

    class Player{
    string firstName,lastName;
    DOB dob;
    string debutPlace, homeTown;
    //a few methods and constructors also go into this class design
    }

    class Batsman : Player{
    int runsScored, fiftyScored,hundredScored;
    float battingAverage;
    // a few methods and constructors are also part of this class
    }

    class Bowler : Player{
    int oversBowled,wicketsTaken, runsGiven;
    float bowlingAverage;
    //a few methods and constructors are also part of this class
    }

    Now I want to create a new class called AllRounder. Going by the real-time characteristics of this object, an AllRounder in cricket is someone who is both a batsman and a bowler. As such I would have to create the AllRounder Class which has both Batsman and Bowler as its base classes.

    Here is where I am starting to face the problem.

    I understand that C# does not support multiple inheritance, but then again Multiple Inheritance can be achieved using Interfaces. Now every book stops with just this and gives a simple example on the same, but I haven’t found a proper suggestion/solution to this problem of mine (I am told that the problem I am referring to, is named as Diamond Inheritance Problem)

    Until I was playing around with C++, this wasn’t a problem at all for me, since C++ supports multiple inheritance and also because Diamond Inheritance problem was solved by C++ by the help of virtual inheritance, which helped me inherit just one copy of the Player class on to my AllRounder class (without having to worry about me getting a copy of the Player class attributes through both the Batsman class and the Bowler class which are to be the base classes of AllRounder class as per my class design)

    All people to whom I have approached with this problem, said Interfaces is my solution. But I understand that interfaces can only contain method signatures and cannot contain any data members. Java is a little bit different on this, the interfaces in the world of java lets you have data members also, but there also comes a limitation, the data members can only be constants.

    My entire class design is trying to map the real time entities and the way they are visualized into classes, but because of the fact that multiple inheritance is not supported, I am not able to proceed further.

    Can someone please help me with this query ?

  2. #2
    Join Date
    Jun 2008
    Posts
    18

    Re: Diamond Inheritance Problem - C#

    Interfaces are just templates of what a part of a class should look like. It specifies the methods that can be seen by the outside world, it doesn't actually implement any code.
    So you have 2 interfaces IBowler and IBatsman. Then you create you 4 objects.
    Code:
    class Player { ... }
    class Bowler : Player, IBowler { ... }
    class Batsman : Player, IBatsman { ... }
    class AllRounder : Player, IBowler, IBatsman { ... }
    Inheriting from Player does actually give you data members and methods. Inheriting from the interfaces simply say that these specified methods exists. You will have to implement them each time for each object. Now when you are iterating over player objects, you can test to see if the player is an IBowler or IBatsman "object" AllRounder would be applicable to both.

  3. #3
    Join Date
    Jul 2008
    Posts
    8

    Exclamation Re: Diamond Inheritance Problem - C#

    Hi
    Thanks for the prompt reply.
    But the problem is since the interfaces (As highlighted by you) IBowler and IBatsman arent allowed to include any data members, how would I go about defining the specific attributes of a bowler class and a batsman class is what I am not very clear about.

    Would it mean that I would have to revamp my class design and include all the attributes of a batsman and a bowler again in the class "AllRounder" ?

    Wouldnt this be a redundancy of attributes while defining AllRounder class, because an allrounder class basically should include all attributes that a Player, Batsman and a Bowler possesses and also if needed add its own AllRounder specific attributes.

    But if I were to declare something like this
    class AllRounder : Player, IBowler, IBatsman { ... }
    then I would essentially have to re-declare all the Bowler and Batsman attributes in the AllRounder class ?

    Kindly clarify. Hope am not going round in circles seeking a clarification here.

  4. #4
    Join Date
    Apr 2006
    Posts
    220

    Re: Diamond Inheritance Problem - C#

    I have understood your problem and I really liked the question you asked. I think you can not achieve what you want to using C#, with inheritance. But you can simulate a bit of similar behavior using composition. Your Allrounder class can contain and instance of Bowler and an instance of Batsman.

    and by the way, where are the umpires and wicketkeeper :-)

  5. #5
    Join Date
    Mar 2002
    Location
    St. Petersburg, Florida, USA
    Posts
    12,125

    Re: Diamond Inheritance Problem - C#

    You declare PROPERTIES.

    btw: Fields should ALWAYS be private.
    TheCPUWizard is a registered trademark, all rights reserved. (If this post was helpful, please RATE it!)
    2008, 2009,2010
    In theory, there is no difference between theory and practice; in practice there is.

    * Join the fight, refuse to respond to posts that contain code outside of [code] ... [/code] tags. See here for instructions
    * How NOT to post a question here
    * Of course you read this carefully before you posted
    * Need homework help? Read this first

  6. #6
    Join Date
    Jul 2008
    Posts
    8

    Arrow Re: Diamond Inheritance Problem - C#

    Nabeel
    Thanks for the response. Yes I also had composition as a work around, but wanted to find out if C# does in fact have the same way of doing it, just as C++ lets me do. btw, since I got stuck at the AllRounder class itself, I gave up going further with the Umpire class and the fielders classes...

    TheCPUWizard
    Thanks for your response. Can you please elaborate your response with respect to Properties ? Would be referring to including properties in the interfaces (IBowler and IBatsman) or would be referring to including properties in the AllRounder class. I do understand that interfaces does let me include properties, which can be implemented by the class that inherits the interface, but then again I would be back to square one, of a redundancy of attribute definition in the AllRounder class with respect to incorporating the Batsman attributes and Bowler attributes. Kindly clarify.

  7. #7
    Join Date
    Mar 2002
    Location
    St. Petersburg, Florida, USA
    Posts
    12,125

    Re: Diamond Inheritance Problem - C#

    There is NO redundancy

    Code:
    interface I1
    {
       int Data { get; set; }
    }
    
    interface I2
    {
       int Data { get; set; }
    }
    
    class C : I1, I2
    {
       public int Data
       {
           get {.....}
           set {.....}
       }
    }
    TheCPUWizard is a registered trademark, all rights reserved. (If this post was helpful, please RATE it!)
    2008, 2009,2010
    In theory, there is no difference between theory and practice; in practice there is.

    * Join the fight, refuse to respond to posts that contain code outside of [code] ... [/code] tags. See here for instructions
    * How NOT to post a question here
    * Of course you read this carefully before you posted
    * Need homework help? Read this first

  8. #8
    Join Date
    Jul 2008
    Posts
    8

    Question Re: Diamond Inheritance Problem - C#

    TheCPUWizard

    Hi, I guess you missed out a portion of my question here.

    The redundancy that I am referring to in the piece of code provided by you, is with respect to class C

    I have a class called "Vehicle". I have derived two classes out of "Vehicle" viz., "Aeroplane" and "Ship". Now I am looking to create a new class called "Hovercraft", by deriving from both "Aeroplane" and "Ship" classes, because I have visualised that an object of type "Hovercraft" would essentially have the features of both "Ship" and "Aeroplane". Now this is what C# doesnt let me do.
    Going by your explanation, I can go around creating interfaces for "Ship" and "Aeroplane" and have the class "Hovercraft" implement both these interfaces. But what happens to the data members of "Ship" class and "Aeroplane" class, which I am looking to inherit in "Hovercraft" class. Even though i define properties in the interfaces for "Ship" class and "Aeroplane" class, I still would have to define all the attributes of a "Ship" and an "Aeroplane" while I am creating a "Hovercraft".

    I wanted to know if we had a way of getting this done just as in C++ wherein I can do a virtual inheritance and create "Hovercraft" from "Ship" and "Aeroplane" (Since both these base classes have a common base class "Vehicle" a virtual inheritance would be needed to do away with getting two copies of "Vehicle" attributes). I guess to do away with this is why C# got rid of Multiple Inheritance.

    Kindly let me know if there is a way out of this ?

  9. #9
    Join Date
    Jan 2010
    Posts
    1,133

    Re: [RESOLVED] Diamond Inheritance Problem - C#

    @gunasekaranmca: This thread is from 2008 - it is generally not encouraged to revive old threads; but, since you did, and I didn't notice and made a sample demo project (...), I think it might be helpful to you and others who might be searching the forums if I post it.

    About the original question: To clarify things, the main thing people don't understand when it comes to the diamond inheritance in C# is how to avoid writing duplicate code, if they need to have implementations of classes on every level of the hierarchy. The answer is rather simple - encapsulate the common behaviors (or implementations) into another class, and use composition. IIRC, it was in the Go4 book that they said "composition is a flexible alternative for inheritance".

    This is entirely a design question - C#'s restriction to single implementation inheritance is precisely imposed to avoid various problems and bugs associated with multiple inheritance - diamond problem among them. However, since it allows multiple interface inheritance, it is possible to create a diamond-shaped inheritance ("is-a") hierarchy in C#; furthermore, the classical diamond problem ("which implementation should be inherited") is non-existent here.

    Forget about C# interface types for the moment. As you probably know, the in language-independent context, in OOP the term "(public) interface" simply denotes the set of all public members of a type, which other types can use when they need to interact. Now, C# interface type, aside from defining a new type, represents a contract of sorts, with respect to anything that implements it. A class which implements an interface is simply saying: "I hereby declare that I will provide implementations of such and such public methods, properties, etc..." (to put it that way). These implementations can come from wherever - the interface type doesn't care.

    So, they can come from other objects. In OOP, classes and objects can be used to represent anything - not just some real world thing with various attributes; they can represent imaginary concepts, constructs purely designed for programming-tasks, they can even represent behaviors (which can then be dynamically replaced), and so on. An implementation class can represent a part of the implementation of some other class, and an instance of the implementation class can then be composed into another object to provide that implementation. This also means that it can be shared (the implementation, not the object itself, although that's also possible), so code duplication is avoided.

    It may all sound complicated, but it really isn't, as you'll see from the sample attached.

    Essentially, in the sample, there are four interfaces: A, B, C, D (for this particular occasion, I temporarily abandoned the usual "I" prefix for interfaces, since IA, IB, etc... might be somewhat distracting and harder to read).

    To form the diamond shaped hierarchy, B and C inherit A, and then D inherits B and C. Then for classes implement these iterfaces - ConcreteA, ConcreteB, ConcreteC and ConcreteD. The implementation for, say, A, is extracted and encapsulated into another class, called AImpl, an instance of which is then referenced from all other classes. This way, the implementation for A is written only once. Similar approach is used for B and C. Some comments in the example provide additional explanations. It's a VS2010 project (console app).
    Attached Files Attached Files

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  





Click Here to Expand Forum to Full Width

Featured