There is a good amount of discussion about OOP on this site. One of the major sticking points of OO I think is the plethora of terminology out there, and the lack of simple and clear explanations of that terminology. This meditation is my attempt at doing just that in regards to Object Composition.
I think this is an important thing for this site, and Perl in general. Given the direction of Perl 6 and its emphasis on improving Perl's OO features, along with things like Traits/Roles and other such esoteria starting to show up on the Perl 6 language list, its only gonna get worse around here.
Disclaimer: This is the first draft, and by no stretch of the imagination is it meant to be the final draft. But in the interest of not creating things in a vacuum, I am releasing it for comment by the monks. Remember, the whole point is to keep it as simple and concise as possible.
There are 2 basic methods to object composition; inheritance and delegation. I will describe different approaches to both, as well as explain where I see Interfaces and Traits/Roles as fitting into all this.
This is the most common kind of inheritance. It is your basic "is-a" relationship. A class can inherit the methods and attributes of another class. Usually the derived class is a specialization of the base (parent) class.
A Manager is-a type of Employee which is-a type of Person.
This is less common and greatly misunderstood and under-utilized form of inheritance (IMHO). Its the same "is-a" relationship as Single Inheritance, but with the possibility of 2 or more parent classes.
A Platypus is-a Mammal but it also lays eggs like a Bird.
Mix-ins are partial classes. They are neither multiple inheritance (although they can be multiply inherited) or Interfaces (they do not define the "is-a-type-of" relationship (see below)), but instead they are a way to alter a specific classes behavior. The best example i can think of is from Python and its web server class.
The regular web server serves each request sequentially. But there are 2 mix-ins provided. One to fork for each request, another to spawn a new thread for each request. The mix-ins only override the bare minimum of methods needed to change the class in the way they want to.
One drawback of mix-ins is that they tend to play havoc with inheritance. Just because your parent class accepted a mix-in does not mean your derived class necessarily can. It end up requiring alot of internal knowledge of both the base class, the derived class and the mix in. Also, to really make effective use of mix-ins you must engineer your classes to be mix-in-able, which can at times get really messy.
Delegation is where an object itself contains other objects which it then delegates responsibilities too. This is sometimes characterized as a "has-a" relationship.
The goal is not to mimic inheritance through delegation, but to encourage the encapsultation of multiple classes into the behavior of a single class.
A Car has-a an engine, is has-a set of wheels and has-a climate control system.
This is by far the simplest form of object composition, but by no means the easiest. It is the prefered method of alot of OO Gurus, and C++ programmers in particular.
Interfaces are not really inheritance per-say. A class that implements an Interfaces enters into a contract with all consumers of that class that the methods (implemented or stubs) from said interfaces will be there. Interfaces are best characterized as "is-a-type-of". Interfaces facilitate Interface Polymorphism, which means you can treat an object in a polymorphic manner based upon the interfaces it implements rather than the class it is. This is best shown in an example:
Interfaces have been made popular by Java. In Java, Interfaces do not have an implemetation, and instead are just markers to indicate that a class will implement a set of methods. This is not a rule for Interfaces, instead it is a rule for Java.my ($list) = @_; my @clones; # check that $list implements # the Iterable interface if ($list->isa("Iterable")) { # the Iterable interface implements # the iterator method, so we call it my $iterator = $list->iterator(); # now make sure that the $iterator # returned actually implements the # Iterator interface ($iterator->isa("Iterator")) || die "bad object interface : no +t Iterator"; # now that we know we have a proper # Iterator, we can be assured it will # implement the hasNext and next methods # so we can use them with confidence in # what they will do. while ($iterator->hasNext()) { my $item = $iterator->next(); # now after getting the $item from the # Iterator, we want to clone it (if possible) # and so we first check to see if the $item # implements the Cloneable interface, which # tells us that the object will clone itself # when the method clone is called push @clones, $item->clone() if $item->isa("Cloneable"); } } # at this point @clones is filled with all # the items in the given list that are able # to be properly cloned
Traits are a concept which is being discussed for inclusion into the Perl 6 object model. As i understand traits, they are like mix-ins where the trait itself is not a complete class, and only a piece of it. They are also like interfaces in that an object which has a certain trait is expected to respond to the methods of that trait.
Traits are meant to be incomplete as a class, but yet complete as a concept. This avoids the need to understand the class internals that usually comes with mix-ins. It very nicely maps to the ideas of traits in the real world, where a trait is just one facet of a person's personality, or aspect of their physical being. To use our single inheritance model:
A Employee is-a Person.Of course, this example is in a perfect world, we all know that just cause your a manager doesn't mean you know how to manage anything at all :)
A Manager is an Employee who has managerial traits.
Traits do not have internal state and therefore do not force any internal fields upon the object. They can however insist the object implement a certain set of methods.
|
---|
Replies are listed 'Best First'. | |
---|---|
Re: Object Terminology (and an awful shaggy dog story)
by Ovid (Cardinal) on Jan 11, 2004 at 20:52 UTC | |
by stvn (Monsignor) on Jan 12, 2004 at 17:53 UTC | |
Re: Object Terminology
by gmax (Abbot) on Jan 11, 2004 at 20:37 UTC | |
by stvn (Monsignor) on Jan 11, 2004 at 21:59 UTC | |
by Coruscate (Sexton) on Jan 12, 2004 at 07:55 UTC | |
Re: Object Terminology
by chromatic (Archbishop) on Jan 11, 2004 at 21:57 UTC | |
by stvn (Monsignor) on Jan 11, 2004 at 22:08 UTC | |
by chromatic (Archbishop) on Jan 12, 2004 at 00:05 UTC | |
by stvn (Monsignor) on Jan 12, 2004 at 01:06 UTC | |
by duff (Parson) on Jan 12, 2004 at 03:36 UTC | |
| |
Re: Object Terminology
by EdwardG (Vicar) on Jan 12, 2004 at 10:28 UTC | |
by stvn (Monsignor) on Jan 12, 2004 at 14:32 UTC | |
by oylee (Pilgrim) on Jan 12, 2004 at 16:33 UTC |