C# and multiple inheritance

Started by
3 comments, last by frob 14 years, 10 months ago
I have a situation in my project where objects are laid out as follows: - WeaponTemplate inherits from ItemTemplate inherits from ObjectTemplate - WeaponInstance inherits from ItemInstance inherits from ObjectInstance - NPCTemplate inherits from PCTemplate inherits from ObjectTemplate - NPCInstance inherits from PCInstance inherits from ObjectTemplate This system follows some rules, too: 1) Every instance initialized from a template copies data members from the template to itself, so that they can be later changed (e.g. the template only influences the initial state of the instance, not its state throughout its entire lifetime) 2) Instance child classes need data members and methods from 2 parents: the template 'above' them and the instance 'above' them in the class hierarchy tree. The breakdown is that, I need ItemInstance to inherit from ItemTemplate AND ObjectInstance -- it needs the 'templated' members as well as the 'instanced' members from the respective classes. I need NPCInstance to inherit from NPCTemplate AND PCInstance -- it needs the 'templated' members as well as the 'instanced' members from the respective classes. So I figure I have the following options: #1 - Switch to another language which permits multiple inheritance - not an option. #2 - Do away with 'template' and 'instance' versions of the classes, and simply manage 'template' and 'instance' lists of the same class. I'm leaning toward this, though there is some wasted space for unused 'instance' variables in template objects. #3 - Use multiple Interfacing - not an option, since the base classes must also possess member variables in addition to methods. #4 - Store references to 'template' objects inside 'instance' objects. This seems an inelegant solution (less so than #2). #5 - Use auxiliary classes to induce inheritance the way I want it to work, e.g.
class ObjectTemplate
class ObjectInstance: ObjectTemplate
class ItemTemplate : ObjectTemplate
class ItemTemplateAuxObjectInstance : ObjectInstance
class ItemInstance : ItemInstanceAuxObjectInstance 

This has obvious drawbacks, most obviously of class hierarchy complexity. I'd like to know if folks here have come across situations, and if you have, how did you handle them?
Advertisement
Quote:
#4 - Store references to 'template' objects inside 'instance' objects. This seems an inelegant solution (less so than #2).

This is basically composition instead of inheritance, and is in fact generally consider preferable. Seems like it would be the ideal method here.
This seems overly complex. NPCs aren't drastically different from PCs. A change in the behavior can be dealt with via the strategy pattern rather than inheritance. Templated objects aren't drastically different than their concrete kin, why differentiate via types?
Quote:Original post by DarkHorizon
#3 - Use multiple Interfacing - not an option, since the base classes must also possess member variables in addition to methods.


Couldn't you have your base interfaces have properties that that your derived classes could then implement themselves? That seems to me like it would get around the issue of your base classes needing member variables.

The overall design though seems needlessly complex to me though. Maybe I'm not understanding it enough, but I don't see why you need Template and Instance classes.
There isn't enough information in your post for a detailed discussion. We'd need to know the design decisions and thought process behind them, which would take a lot of effort.


Multiple inheritance is for when your objects need to be used as the parent class. It looks like you just want to copy the parent's functionality, perhaps delegating work by requiring a common interface among your classes.

One option is to put the algorithms elsewhere and go with the Strategy pattern to delegate the work.

Another option if you have more complex relationships is to use the Visitor pattern for the various commands.

There are undoubtedly additional options, but without knowing your designs and goals it really would be difficult to discover them.



There are very few reasons that multiple inheritance is absolutely necessary. One example is when you have an object that needs to be passed between multiple external libraries and for some reason cannot be built by composition. But when it really is absolutely necessary it is a drawback. One common workaround is to write a conversion operator to the other class, but that doesn't play nicely with the 'as' operator and a few other built-ins. Fortunately this is an extremely rare necessity.

This topic is closed to new replies.

Advertisement