By using composition and interfaces instead of inheritance, class relationships become more explicit and the design becomes more flexible. Inheritance is useful for centralizing functionality and enabling polymorphism at the same time. However, inheritance is often used for centralization or polymorphism and not both. A design that uses CompositionInsteadOfInheritance and InterfacesInsteadOfInheritance make class relationships explicit: Either you want polymorphism, or shared functionality. Using only interfaces and composition, code becomes easier to ReFactor: There is no longer a static link between classes and their super classes. And references to shared functionality becomes explicit rather then relying on inheritance fall-through rules. '''Impossible. My design requires class inheritance.''' Any class inheritance can be changed to an interface inheritance and composition relationship: Create a common interface and refactor common functionality. See PolymorphismAndInheritance. '''This means I would have to do delegation everywhere.''' Yes. Class inheritance does this for you implicitly, but composition makes the relationships explicit. ''On the other hand delegation can be a real pain in some languages. C++ (and probably Java) delegation involves copying each public method signature and writing a little method body that forwards the call. It also means you maintain two instances of the method when something changes, like the constness of the method or the return type or the constness of a parameter etc., etc... Any changes are then spread across four files: two .h files and two .cpp files.'' [edited] Not only does delegation in C++ and Java mean writing more code, it is also not as performant as class inheritance. Implicit delegation by inheritance needs constant time, explicit delegation is linear. ''In PythonLanguage, on the other hand, delegation can be achieved with as little as one extra method to delegate to one or more classes. Altering the number of parameters of a delegated method often requires a change to only one module.'' '''I would have to make an interface for every class.''' No. You would only create interfaces where you want polymorphism. '''I need protected methods. This makes them useless.''' Right - that's a problem. The best way I can argue this is that protected methods are unnecessary unless you are writing a library of code for another group to develop against. And in this case you may only want to give them access to an API defined by a set of interfaces rather then to your underlying classes. In this way, all class methods are protected methods, and interfaces methods are public methods. Alternate response: Protected Methods are no longer necessary. Instead of providing the implementation in the base class and using it in a higher class, one implements the methods as public methods in a support class. The user classes contain the support class as a private member. This has no affect on the external, public interface of the child class and avoids a lot of dependencies that result from protected class declarations. (See also: MethodsShouldBePublic) '''How do I extend classes?''' Implement the interface and delegate to the class that you would have extended. See DelegationInheritance. '''One minor problem: how does the delegated class delegate back, since it loses the polymorphic dispatch on this (self)?''' ---- The single benefit cited here is explicit delegation, which may or may not save you time refactoring. YouArentGonnaNeedIt. If inheritance is the SimplestThing, do that. If it ceases to be the simplest thing, ''then'' refactor to CompositionInsteadOfInheritance, not before. In my experience, the time saved with implicit delegation is usually greater than the rigidity of inheritance. When it's not, that's when I use composition. ---- [edited] Inheritance done by anyone with half-decent skill often increases readability and reduces SpaghettiCode. For more discussion of this, see RavioliCode ---- Isn't this what we have to do to get InheritanceInVbClassic? And everyone said how sad we were. Same for COM, which has no inheritance. CORBA folks loved bashing COM about this. Interestingly, Microsoft's new component model, .Net, has inheritance. CORBA does not have class inheritance. It only has ''interface'' inheritance. COM also has interface inheritance (e.g. all interfaces inherit IUnknown). The only advantage CORBA has over COM is multiple interface inheritance; COM uses the QueryInterface method to implement multiple interface inheritance. ---- '''How do I create an Aggregate Class?''' Often times I need to create a large class that is just the aggregation of several smaller classes. For example, a Person class may consist of a Name class and an Address class. My application may wish to organize people by last name in some cases and state of residence in others. Having a Person class inherit directly from a Name class and an Address class is the simplest solution. The alternative becomes having the Person class inherit a Name interface and contain an embedded Name class, and also inherit an Address interface and contain an embedded Address class, with all of the necessary delegation. "Having a Person class inherit directly from a Name class and an Address class is the simplest solution." ''Is it? I would have thought creating an iterator or comparator for each sort order would be much simpler. -- JimArnold'' But how do you link the two classes? It does no good to sort the addresses if I can't get to the corresponding names and vice-versa. ''If Person'' has-a ''Name and Address, your link is the Person itself. This seems trivial to me - maybe I'm missing something fundamental in your argument? -- JimArnold'' : I'm very interested in hearing a defense of this statement. It goes directly against the conventional wisdom. Person is-NOT-a Name or an Address, therefore it should not inherit from Name or Address classes. Person has-a Name and Address, therefore it should contain two fields/properties/term du jour of those types. What does inheritance possibly buy you in this case? '''Depending upon your programming context, you could apply either a is-a or a has-a relationship. This is largely a subjective decision, and in some contexts, the definition of a Person class may very well be that it is a Name and and Address. For a more detailed description of why this important programmatically, I have pulled a section of this discussion out and inserted it below (way below - look for the pseudo-code definition of the Person class as containing a Name class and Address class.) Inheritance exposes the Person interface so you can perform Person operations without having to create a gazillion delegation methods. ''But why do you need delegation methods? If you're going to tie Person to Name and Address via an abuse of inheritance, why not abuse the LawOfDemeter instead and reference Name and Address through Person?'' class Person { public Name name; public Address address; } ''-- JimArnold'' Pick your form of SelfAbuse then :-) The advantage of inheritance is that you can override methods. With the direct access, there's no way for a container to add an interceptor layer between itself and what it contains. : ''I still don't get your point. Why would you need to override methods of something like Name or Address? The only half-baked example I could think of would be something like wanting to perform some action when the Person's Name is set. But surely in that case it would be preferable to have a class SpecialName (I know that's a lousy class name) that inherits from Name, and then have Person be composed of SpecialName and Address, no? What benefit do you get from conflating Person and Name?'' Why insert yet another class. For example, I have to check names for special characters that we don't allow. In the container class i could override SetPersonName to do the check and then call the base class SetPersonName if it passed. Why have a special name class. Your problem in creating the class name indicates that it is an unnecessary fiction. : ''I did say the example was half-baked. :-) But we come pretty close to agreeing. If you need to eliminate a special set of characters from a name, you're not dealing with a general Name, but rather a NameWithoutSpecialCharacters, or maybe WellFormedName.'' : ''But if Person inherits directly from the general Name class, and override some method(s) to handle the special character elimination, the exact nature of the overridden methods tends to become obscured. You've really got a PersonWithWellFormedName, but every time it may be useful to know that, you have to re-read the overridden method to figure out the exact nature of the changes relative to the base implementation. The code doesn't just _tell_ you what's going on. And even if you try to name the Person class in such a way as to tell you its exact nature, you face a combinatorial explosion - PersonWithWellFormedNameAndSpeciallyProcessedAddress is kinda unwieldy.'' : ''In a nutshell, the reason for adding another class is that it provides you with the opportunity to name the class in such a way that its nature, or how it differs from the base case, is clear. Having Person inherit directly from Name misses that chance, and forces you to dig that information out of the code every time you need it.'' : ''There is also the off chance that you could have a Product class that needs the same characters removed from the product's name. With direct inheritance, you end up with duplicated code, the same method overridden in the same way in both Person and Product.'' The validation code would likely be in a separate class that would be reused so there's no duplication. The class inheriting person name imposes the naming constraints so it makes sense for it to implement the constraints. Creating another class doesn't clear up anything to me, it makes it more confusing because the constraint code is put in another class that has nothing to do with it. : ''I'm confused. Did we just agree? If the code that ensures that the name doesn't include special characters exists in a class separate from Person, isn't that class the equivalent of the WellFormedName class I mentioned?'' : ''The situation seems to be that you have a requirement that says "A Person has a Name. That Name must conform to certain constraints to be considered valid."'' : ''I'm saying that those constraints are constraints on Name, not Person, and thus the code implementing those constraints should go in the Name class, or at least a well-named subclass of Name. If you don't agree, then I interpret your position to be that Person should inherit from a generic Name class, then enforce the constraints itself by making calls to a third class that just contains constraint code. If this is accurate, what is that third class called? Is it a domain object, or just a utility class?'' My case is a semi real-life example. The string validation isn't a function of person in this case, but is a function of special DOS related characters because we use some names as file names. So person wouldn't care about the characters. What cares is an object that is persisted to a file that contains a person. So the persisted object wants to check that person name doesn't contain special characters that DOS doesn't like. Person doesn't and shouldn't care about this layer of validation. It's certainly not reason in my mind to make a separate class. I should also state that the container class does other validation such that making just a separate class for for the persistable version is more work, IMHO, than it is worth, since these are all constraints of the container class, and are not intrinsic to person of of another class derived from person. : ''Hmm. Your problem may be different than I was originally thinking, but I'm still not sure I understand. Let me restate what I think you just said.'' : ''Your system contains a Person object whose name, let's say, is "John Doe". This object may get persisted to a file. If so, that file would be named something like "John Doe.txt" Thus, you want to ensure the person's name doesn't include characters that can't be used as part of a file name. When an object is persisted to a file, other validation checks are performed on it in addition to checking for the invalid name characters.'' : ''Is that an accurate description of your situation?'' That's correct. : ''Ok, then I think it's perfectly valid that your PersonPersister class implement whatever checks are necessary to persist your objects.'' : ''But I wonder what happens when a Person object shows up with an invalid name. Why let invalid data into your system in the first place? If you check for invalid characters when the name is first assigned, as would happen with a WellFormedName class, you would detect the error at the earliest possible time.'' Good point. It is at a user boundary over messaging interface so we can't control what people sent. We also have to handle deliberate denial of service type attacks. : ''You know, I thought we were about to agree, but after re-reading this whole thread, I just don't get why you're doing what you're doing. Your design seems inside-out and backwards.'' : ''The best reason for having Person inherit from Name would be so that you could use an instance of Person where an instance of Name was expected. But saying "thePersistentFile.Name = Person" is silly. Why use inheritance here?'' : ''Then, you have rules for determining whether a name is valid. But you want to make Person responsible for enforcing the validity rules on Name. Why? Why not let a NameWithoutSpecialCharacters class be responsible for itself?'' : ''Thirdly, you want your "PersonPersister" class to validate Person objects before persisting them. Why not just give Person a "persist()" method and put the validation code there? Your PersonPersister then just becomes a loop that calls "aPerson.persist()" on each Person object it wants to persist.'' : ''Here is some c# pseudo-code describing what I'm talking about. Notice that the rules for validating names are inside the NameWithoutSpecialCharacters class. No other class knows or cares about them. The rules for validating Person objects are likewise inside the Person class. No other class cares about them. PersonPersister very simply tells Person objects '''what''' to do ("persist yourself"), not '''how''' to do it. It doesn't care how the Person object does it, just whether or not it was successful. Each class only worries about its own little job. Why would you not do it this way?'' class PersonPersister { private Person[] myPeople = new Person[10]; public void Persist() { for each (Person aPerson in myPeople) { try { aPerson.Persist(); } catch (System.Exception anException) { // oops! handle the problem. } } } } class Person { private NameWithoutSpecialCharacters myName; private AddressWithMaybeSomeSpecialProcessing myAddress; public string Name { get { return myName.Value; } set { myName.Value = value; } } private bool IsValidForPersistence { get { // whatever checks need to be done to validate this Person go here. // (_not_ including special character checks - those go in // NameWithoutSpecialCharacters } } public void Persist() { if (IsValidForPersistence) { // write this object to a file. } else { raise System.Exception; } } } class Name { private string myName; protected virtual bool IsValid(string aName) { return true; } public string Value { get { return myName; } set { if (IsValid(value)) { myName = value; } else { raise System.Exception; } } } } class NameWithoutSpecialCharacters : Name // NameWithoutSpecialCharacters inherits from // Name { protected override bool IsValid(string aName) { if (aName contains special characters) { return false; } else { return true; } } } ---- The best reason for having Person inherit from Name would be so that you could use an instance of Person where an instance of Name was expected. But saying "thePersistentFile.Name = Person" is silly. Why use inheritance here? Polymorphism wouldn't be the primary reason for Person to inherit from Name. The reason would be to provide the name interface without having to write a bunch of delegation methods in such away that a layer of indirection by overriding some methods can be added. ''What delegation methods are you talking about? Look back at my example again. In the Person class, I just made the Name and Address fields public to emphasize that no further getters/setters are really necessary in that class. You've mentioned before wanting to override methods in the base Name interface. In my example, that code exists in the NameWithoutSpecialCharacters class. Exactly the same stuff you already said _needs_ to exist. What extra methods are you talking about? There is none.'' I would never make data public so perhaps there's a difference there. The methods would be to set and get the name that would delegate to the Name methods. ''Ok. I changed the Person class back to the original form I presented, with the myName and myAddress fields declared as private. I also added a public Name property to demonstrate the delegation that's giving you problems. Five lines of code. You say below that "In this case, [inheritance] buys you a lot." You and I have a different definition of "a lot".'' I would need to override the set to check for DOS-related characters, not special characters in general. NameWithoutSpecialCharacters is wrong because it doesn't capture what is going on. ''It's not wrong; it's just pseudo-code. You earlier used the phrase "special characters that DOS doesn't like". I just tried to condense that somewhat to make the class name less unwieldy. Call it NameWithoutSpecialCharactersThatDosDoesntLike if you want.'' ''You've said a couple of times in this thread that, if you use inheritance, you have to override one of the methods of the Name interface inside the Person class in order to implement the character elimination logic. That is exactly what goes in this class. In the IsValid method, to be exact.'' ''I added the base Name class to my example above to demonstrate that the definition of NameWithoutSpecialCharacters involves overriding just the method that validates the string being assigned to the Name object. This is exactly the same logic you would have to add to you hybrid Person class, its just located in the class responsible for implementing special names.'' It's not my fault the only way to do this in C++ requires ISA. I take that back. As person has a name and if I want to pass that to something that expects a name, ISA makes that very convenient. It seems you are being slavish to reality. Programs aren't reality. There's no reason not to say Person ISA Name if it buys you something. In this case it buys you a lot. A language with different capabilities would cause me to make different choices. ---- "Polymorphism wouldn't be the primary reason for Person to inherit from Name." ... MakeReservation(const Name& customerName) {} Person p("fred"); MakeReservation(p); ''To pick a nit, you contradict yourself. Being able to use Person objects polymorphically in calls to MakeReservation is '''exactly''' the reason you've put for for having Person inherit from Name.'' ---- "As person has a name and if i want to pass that to something that expects a name, ISA makes that very convenient." ''Can you give me an example of this convenience? Some code snippet that shows me how having Person inherit from Name is more "convenient" than the sample code I wrote above? To me, it looks like no matter whether you use inheritance or containment/composition, as in my example, in either case you can say "thePersistentFile.Name = aPerson.Name". What else do you need? What benefit does inheritance provide? What code does it prevent you from having to write?'' MakeReservation(const Name& customerName) {} Person p("fred"); MakeReservation(p); ''Ok, we're just never going to agree on this. I honestly don't mean this as a flame, but in my mind, this is simply lazy programming. You're intentionally misrepresenting the relationships of your classes, pretending a Person is a Name, just so that you can type "p" instead of "p.name". Why don't you have MakeReservation accept a parameter of type Person rather than Name, and avoid the whole issue?'' ----- ''But why do you need delegation methods? If you're going to tie Person to Name and Address via an abuse of inheritance, why not abuse the LawOfDemeter instead and reference Name and Address through Person?'' class Person { public Name name; public Address address; } Why is this an "abuse of inheritance?" The approach above does not allow me to use sort and search methods created for collections of Name objects or Address objects. If I want to list the names of people with an address in the state of Nebraska, I have the following options, 1) Use an existing search method based on collections of Address objects to find all Address objects with the state set to Nebraska and then do a search through my collection of Person objects to match the Address objects to the Person objects and then retrieve the Name objects. 2) Create an address search method for Person objects that duplicates the operation of the search method written for Address objects and continue to maintain duplicate code. 3) Have a Person class inherit from both the Name class and the Address class, allowing all operations written for the lower level Name and Address classes apply directly to the Person class as well. ---- OK, can we start signing our comments? This is getting confusing. There are (at least) three people talking here. To answer the above, the reason it's an abuse of inheritance is because you're enforcing Person's interface in the wrong way. If Address has an IsInState(State state) method, and you want the same method on Person, factor it into an interface that both classes can implement (ILocatableByState or whatever). I can understand your argument that Person is-a Name and Address, but I think the semantics are wrong. Person is-composed-of a Name and Address, and it is LocatableByState (as is an Address). -- JimArnold ''And what is wrong with implementing composition by inheritance if it gives you demonstratable benefits when building a program? We are not talking in the abstract here. We are talking about creating a program to do something. Inheritance has benefits when implementing composition. Why not take advantage of that?'' I have yet to see any demonstrable benefits of using inheritance in this situation. ''It is often very hard to demonstrate something to someone who doesn't agree in the first place. For me, not having to delegate (or expose public data), having the ability to silently extent functionality, the ability to override just the methods I want without interposing another class, and the ability to use ISA to simplify argument passing, are all reasons enough. It is the simplest thing. Composition is much more verbose and complex and has no demonstrable benefits.'' ''Let me take one last stab at this:'' ''Delegation - if you use composition, yes you'll have to write delegation methods. But at five lines per, as in my example above, if this _really_ a big burden? I used to program in VB6, and even in that environment, I was able to write an addin that allowed me to automatically generate the delegation code.'' ''"Silently extending functionality" - I'm not sure what you mean by this.'' ''Overriding methods without adding another class - In my example, the overriding you'd do in the NameWithoutSpecialCharacters class is exactly the same as you'd have to do in your Person class? And it associates rules for validating names with a class that defines a type of name. Why is that a problem? See FearOfAddingClasses, perhaps?'' ''Simplified argument passing - You are only saving yourself five characters worth of typing. And you're presenting a conundrum to any future maintenance programmer. Your MakeReservation routine takes a Name argument, but you pass it a Person. There's no reason inherent in your problem domain (at least that you've told me) why Person should inherit from Name. Indeed, you're only doing it for coding convenience. That would definitely confuse me, if I were the maintenance programmer, possibly making me waste time chasing a RedHerring, instead of the real bug I was after.'' ''"Composition is much more verbose and complex..." - I vehemently disagree with this. Composition is only slightly more verbose, at worst. And the additional code is very simplistic. Five simple lines, in my example. But that's the lesser issue.'' ''Composition is less complex because the code says exactly what its doing. A person has a name, so a Person class has a field of type Name. You want to sort Person objects according to their names, so you have a sort routine that accepts a collection of Person objects, accessing and comparing their name fields. Given just a description of the problem ("sort these people according to their names"), there's no way to reason your way to an explanation of why Person should inherit from Name. Why would you purposely undermine the ability to reason about your solution in the same way you reason about your problem?'' The analysis domain and the implementation domain are fundamentally different. One is the best way to solve a problem and the other is the best way to implement the solution to the problem. If you don't make this distinction then you don't and we just do things differently. From my experience all the extra work is a nightmare to maintain without a sufficient reason to do it. There is nothing compelling in your arguments. ''Nor in yours. Yes, we simply see the world differently. C'est la vie.'' "Silently extending functionality" means that when interfaces are used i can add new functionality by adding a method and I don't break anyone who doesn't use it. In composition i would have to add a delegator to every class just to pass the functionality through to a low layer who may use it. ---- In regards to your sorting issue, the basic problem is that your code suddenly changes its mind about what is important in the world. From what you've told me, manipulating Person objects is the primary purpose of your code. It creates a collection of Person objects based on data from an outside source, persists those Person objects to files, and now wants to sort those Person objects based on their names or addresses. But the code that does the sorting suddenly takes the view that Name or Address objects are its primary focus. It literally sorts collections of Name or Address objects, then has to somehow link those objects back to their corresponding Person objects. This change of focus is causing your problems. You really need sort (or search) routines that operate on collections of Person objects, sorting them based on the value of their Name fields. By keeping the code focused on operating on Person objects, you eliminate the need for this "a Person is-a Name" fiction. ''Or I use the existing search and sort operations. Do you have a stronger argument beyond some personal intellectual purity? Sure, we could write (and rewrite) additional code to accomplish this, but why?'' ---- I think the core problem is "search methods created for collections of Name objects". Why isn't it simply "search methods created for *collections*.", period? Using the convention of Java's collection library, you would only need *comparators* of Name objects and use the library search methods to do the searching (similar for sorting). So to search/sort the collection of Person objects based on name, just create a new comparator for Person objects which delegate to the Name comparator. -- OliverChung ''Indeed. Excellent point.'' Look at this from the perspective of the Address class. We have multiple things that have addresses. We would like to be able to use and add address searches for all of these higher level classes. Having to add a new address search/sort and the delegators to all possible user classes is difficult in maintenance. It is also frustrating to have an expected search/sort fail because of a missing delegator, and it becomes tempting to add a new comparator at the higher class level. Remember, we are trying to simplify software. ---- ''Nor in yours. Yes, we simply see the world differently. C'est la vie.'' I don't think there is a compelling argument either way. But I'm not trying to tell that world there is only one way, as is this page. ---- Unfortunately this discussion doesnt seem to address the concept of Composition and Interfaces very well, and focuses more on what is (and has been mentioned) Convenience Inheritance. I think the discussion about when to use composition instead of class inheritance covers a much wider problem space than the one presented here. Maybe this should be given a new location, maybe called ConvenienceInheritance, possibly extended to ConvenienceInheritanceInsteadOfComposition. I think the idea of TaxonomicalInheritance, with regards to using composition/delegation would be more enlightening for this topic (maybe its been presented elsewhere but I havent seen it so far). --NickRobinson ---- See: WeDontUseInheritanceEnough ---- The ScarletLanguage uses an object model that is exactly like this except that the delagation is handled automatically. Objects are composed of one or more implementations that implement interfaces. There is no implementation inheritance and the aggregated implementations are treated as a single object. This leads to very fine grained interfaces and implementations that are narrowly tailored to one purpose. So, it's easy to assemble new types by throwing together implementations or to customize existing types (even the standard library types) by adding a new implementation or by replacing an old one. ---- CategoryPolymorphism