#3: Complicated Inheritanceby Richard Bartle In my previous article, I described inheritance in terms of trees. A tree consists of a set of nodes, with one such node designated the trees root. Each node has a set of children, each of which is either the root of its own sub-tree or is a leaf (i.e. it has no children). Non-leaf nodes are classes; leaf nodes are instances of their parent class. Trees are acyclic, in that no node can be its own ancestor (you cant have X derives from Y, Y derives from Z and Z derives from X), and directed (the relationship between parent and child is non-reflexive). OK, so why is this bad for MUDs? Single Inheritance In a tree, each node can only have one parent. In a MUD, definitions are so much easier if nodes can have two or more parents. Example: suppose you come across a crocodile, a tiger and an elephant together in the same room. If your character is a sahuagin, you might want to leave your cold-blooded compatriot alone and would therefore wish to KILL MAMMALS; if your character is a minotaur, you might want to leave your fellow herbivore alone and therefore KILL CARNIVORES. In the former case, youd want to attack the tiger and the elephant; in the latter, the tiger and the crocodile. The thing is, the tiger is both a mammal and a herbivore. In a tree-based, single inheritance system you have to choose just one parent for the TIGER class (MAMMAL or CARNIVORE); you cant give it two parents as that wouldnt produce a tree. So which do you choose? They both seem equally valid. Other examples are trivially easy to think of. Is a dollar bill MONEY or PAPER? Is a pitchfork a TOOL or a WEAPON? Is the ace of spades an ACE or a SPADE? Was Shakespeare a PLAYWRIGHT or a POET? Whats needed is multiple inheritance. Multiple Inheritance In multiple inheritance, youd say that a tiger was both a MAMMAL and a CARNIVORE. It would inherit from both its parents. You could add other parents too, perhaps JUNGLECREATURE and FIREHATER. It depends what classes you find a need for in your game. This approach also addresses the very common MUD problem of similar objects not having similar methods. In Trials, Triumphs & Trivialities #20, Shannon Appelcline gives an example where LONGSWORD derives from WEAPONS (because it hurts people) yet BROADSWORD derives from SMITHERY (because its made of metal), both via different intermediate classes that happen to share the name SWORD. In a multiple inheritance system, youd just have the one class, SWORD of which LONGSWORD and BROADSWORD are instances, and make SWORD inherit from both SMITHERY and WEAPON. Youll have noticed I changed the name from WEAPONS to WEAPON, there. This is because the relationship between child and parent in inheritance systems is "is a kind of"; SWORD is a kind of WEAPON, its not a kind of WEAPONS. Strictly speaking, I should probably have used WEAPONRY rather than WEAPON, but lets not be too pedantic... Other parent/child relationships are also possible, by the way, for example "is made of" and "is a part of". These have their uses, but in MUDs you almost invariably want to inherit along an "is a kind of" line, so thats the one that should be hard-coded in. We dont have a tree any more, of course. What we have is a hierarchy: Hierarchies can get very, very complicated to illustrate graphically, with nodes having parents drawn from all over the data structure at wildly different distances from the root. All but one of the basic rules are the same as for trees, though: theyre directed (they have a parent/child relationship), acyclic (there are no loops) graphs. Only the number of parents for non-root nodes has changed, from 1 to whatever takes your fancy. That single change, however, results in a superbly more expressive system. It is just incredibly easier to describe an object in terms of multiple existing classes instead of just one, and they can also inherit far more functionality than they ever could in a single inheritance approach. If its that great, then, why doesnt every MUD have multiple inheritance? Issues with Multiple Inheritance There are two issues with multiple inheritance. The first issue is what to do about clashes. If, in the above example, the default weight of a WEAPON were 2kg and the default weight of SMITHERY were 5kg, whats the default weight of a SWORD? It inherits from both, and neither has any more entitlement to win than the other. Actually, it doesnt really matter! After all, what is the default weight of a sword? So long as the system inherits the same value every time, the fact that theres another one it could have taken is immaterial. If youre that bothered about the weight of swords, either explicitly state from which you want to inherit, or overwrite both defaults with a SWORD-specific weight. The second issue? Tsk, Im all out of space for this article. Youll have to wait until next time to find out... |