No, animal -> dog -> retriever doesn't happen, especially in ColdFusion
development for the web! Neither does my Father > Child example. I think I
know how you feel. Inheritance is *supposed *to be there, so you look for it
to show up in your design.

If you come across a use case where you see you would repeat the same
methods in a set of classes, that *might* be a good situation to use
inheritance in ColdFusion at this point. You can create a super-class and
put those repeated methods there, and then all the subclasses can use them,
and you don't have to repeat them in each class.

Some patterns in the OO world simply exist because of strict typing, and
then *type inheritance* plays an important role. So you'll see a lot of
examples using inheritance in OO literature, because it assumes strict
typing.

ColdFusion is more flexible because it is not strictly typed. Somewhere on
your way to becoming a world class OO expert, you may begin typing your
components in CF, but you'll know why you are doing it, and you will have
made that choice wisely. You'll probably be working with a team, or
providing an API, and not overly concerned about the performance hit. But to
begin with, I don't think you should be using strict typing just yet, or
trying to deal with patterns that require type inheritance. Get some
experience under your belt first. If you pass an object into a function, use
type="any", or type="component" if you want to ensure a component gets
passed in.

The consensus in CF development seems to have become that rather than trying
to mimic the way things are done in a strictly typed language, leverage the
fact that CF is loosely typed to your advantage, to save time and reduce
complexity. If the added complexity of introducing typing and patterns that
utilize type inheritance works toward your advantage, again, by the time you
get there, you'll know exactly why you want to use that approach. Until
then, you'll probably almost always use composition, except in the case i've
outlined above.

Nando




> It seems actually having use cases for the animal -> dog -> retriever
> type of relationship doesn't happen all that often. At least it hasn't
> in my app yet.
>
> On May 2, 11:28 am, Nando <[EMAIL PROTECTED]> wrote:
> > The part about PaternalLine tries to explain how the term "inheritance"
> came
> > about. In the example, I'm probably mixing in too many concepts at once,
> and
> > not doing a good enough job of explaining them in separate examples.
> Sorry.
> > Let's leave that aside for a moment.
> >
> > To my mind, you can go 2 ways. One is that you can use inheritance, but
> then
> > you'll need to instantiate ImageService, and probably create a few other
> > similar objects like TextService for instance to handle text.
> ContentService
> > would most likely NOT be instantiated. Content Service would contain
> methods
> > common to handling both text and images, whereas TextService would
> contain
> > methods specific to text (if there are any), and ImageService would
> handle
> > methods specific to images. If that sounds appropriate, then you'd use
> > inheritance and place the extends attribute in TextService and
> ImageService
> >
> > <cfcomponent displayname="TextService" extends="ContentService">
> >
> > Again, to use inheritance, you'll need to refactor your application to
> > instantiate TextService and Image Service, rather than ContentService.
> >
> > If you want to stick with using Content Service, then you'll need to
> either
> > pass an instance of ImageService into ContentService, or create an
> instance
> > of ImageService inside ContentService, most likely when ContentService
> is
> > instantiated.
> >
> > Are you clear how to do that yet?
> >
> > On Fri, May 2, 2008 at 4:11 PM, [EMAIL PROTECTED] <
> [EMAIL PROTECTED]>
> > wrote:
> >
> >
> >
> > > Ok so using this PaternalLine idea, in the parent (which for me is
> > > contentService) it still needs an instance of the child (imageService)
> > > in order to perform any of its functions.
> >
> > > How does the child perform a function of the uncle when they are both
> > > essentially children of PaternalLine? This is how I see the
> > > relationshis the way you explain it, looking just at inheritance:
> > > PaternalLine -> Father -> Child
> > > PaternalLine -> Uncle
> >
> > > The way I see this the child still needs an instance of uncle in order
> > > to perform its functions. So essentally this isn't inheritance
> > > anymore, its composition... Please explain further if It seems that I
> > > am missing something.
> >
> > > On May 1, 7:14 pm, Nando <[EMAIL PROTECTED]> wrote:
> > > > You have a class called ContentService. You notice that besides
> dealing
> > > in
> > > > generic ways with content, it's beginning to deal in specialized
> ways
> > > with
> > > > with various types of content.
> >
> > > > You can then refactor your application and shift the specialized
> methods
> > > > into classes that extend Content Service, let's call them
> TextService,
> > > > ImageService and FlashService. Then you have the following
> components:
> >
> > > > <cfcomponent displayname="ContentService">
> > > >     <cffunction name="ProcessAllTypesOfContent">
> > > >     </cffunction>
> > > > </cfcomponent>
> >
> > > > <cfcomponent displayname="TextService" extends="ContentService">
> > > >     <cffunction name="ProcessText">
> > > >     </cffunction>
> > > > </cfcomponent>
> >
> > > > <cfcomponent displayname="ImageService" extends="ContentService">
> > > >     <cffunction name="ProcessImage">
> > > >     </cffunction>
> > > > </cfcomponent>
> >
> > > > <cfcomponent displayname="FlashService" extends="ContentService">
> > > >     <cffunction name="ProcessFlash">
> > > >     </cffunction>
> > > > </cfcomponent>
> >
> > > > How your application would work now is that instead of instantiating
> > > > ContentService to process content, you'd instantiate the specialized
> > > class
> > > > instead, let's say ImageService. The extents attribute on
> ImageService
> > > makes
> > > > the functions in ContentService available in ImageService. So in our
> > > simple
> > > > example, you'd call imageService.ProcessImage() method first, and
> then
> > > the
> > > > imageService.ProcessAllTypesOfContent() method to finish the job,
> all
> > > from
> > > > ImageService. The variables scope within ImageService would be
> available
> > > to
> > > > the ContentService's methods.
> >
> > > > That's all that inheritance does.
> >
> > > > The term "inheritance" for someone new to this can seem like it
> > > > *should*mean that the parent passes on its knowledge and wealth to
> the
> > > > child, but
> > > > that ain't how it works. The child can use the parent's knowledge,
> but
> > > > doesn't get its instance data.
> >
> > > > So you always instantiate the "child" object, the one with the
> extends
> > > > attribute, to get the job done. The "parent" doesn't know a thing
> about
> > > the
> > > > "child". If you instantiate the parent object, it cannot use the
> child's
> > > > methods or instance data, and in fact has no awareness that it even
> > > *has* a
> > > > child.
> >
> > > > If you are one of those persons who wish that their father took a
> more
> > > > active role in your life and tend to design your applications to try
> and
> > > > make up for it, then here is what you must do ;-)
> >
> > > > <cfcomponent displayname="Father" extends="PaternalLine">
> >
> > > >     <cffunction name="CreateChild">
> > > >         <cfset var Child = CreateObject("component",
> Child).init(this)
> > > />
> > > >         <cfreturn Child />
> > > >     </cffunction>
> >
> > > >     <cffunction name="UseTheCar">
> > > >     </cffunction>
> >
> > > >     <cffunction name="UseCreditCard">
> > > >     </cffunction>
> >
> > > > </cfcomponent>
> >
> > > > <cfcomponent displayname="Child">
> > > >     <cffunction name="init">
> > > >         <cfargument name="Father" required="yes" type="PaternalLine"
> />
> > > >         <cfset variables.Father = arguments.Father />
> > > >         <cfreturn this />
> > > >     </cffunction>
> >
> > > >     <cffunction name="DriveCar">
> > > >         <cfreturn variables.Father.UseTheCar() />
> > > >     </cffunction>
> >
> > > >     <cffunction name="BuyNewMac">
> > > >         <cfreturn variables.Father.UseCreditCard() />
> > > >     </cffunction>
> >
> > > > </cfcomponent>
> >
> > > > In the above example, when the Father creates the Child, notice that
> we
> > > have
> > > > passed "this" into the init() method of the Child, which in effect
> > > passes
> > > > all of the Father's knowledge and instance data into the child. It's
> > > still
> > > > encapsulated within Father, but the Child can make use of it by
> calling
> > > > Father and saying, "Dad, can I have the car keys? I want to go
> downtown
> > > and
> > > > pick up that new MacBook Pro you promised me!"
> >
> > > > In our example above, notice also that Father extends an object
> called
> > > > PaternalLine. Notice also that the init() method in Child only
> accepts
> > > an
> > > > object with the type "PaternalLine" as a Father. In this case,
> Father
> > > has *
> > > > inherited* the type PaternalLine, and what this arrangement allows
> is
> > > that
> > > > the Child can also borrow the Uncle's car and use his credit card.
> His
> > > Uncle
> > > > can stand in as his Father, because his Uncle also extends the
> > > PaternalLine.
> > > > The term inheritance refers originally to this mechanism of *type
> > > > inheritance*.
> >
> > > > <cfcomponent displayname="Uncle" extends="PaternalLine">
> >
> > > >     <cffunction name="CreateNephew">
> > > >         <cfset var Child = CreateObject("component",
> Child).init(this)
> > > />
> > > >         <cfreturn Child />
> > > >     </cffunction>
> >
> > > >     <cffunction name="UseTheCar">
> > > >     </cffunction>
> >
> > > >     <cffunction name="UseCreditCard">
> > > >     </cffunction>
> >
> > > > </cfcomponent>
> >
> > > > In languages that use strict typing such as Java, type inheritance
> is
> > > very
> > > > important. It allows you to program your app so that the Child can
> go to
> > > > either his Father or Uncle to use the car, for instance. ColdFusion,
> > > because
> > > > it's not strictly typed, doesn't need the mechanism of inheritance
> to
> > > > provide this flexibility. You can just use type="any". So in
> ColdFusion,
> > > > unless you're traveling the strictly typed road to ensure that the
> > > Children
> > > > in your application only ask family members to use the car for
> instance,
> > > > inheritance is much less important than it seems to be from reading
> > > pattern
> > > > books and hanging out with people who learned object orientation
> using a
> > > > strictly typed language.
> >
> > > > I hope my example is clear enough ... and doesn't have any glaring
> > > flaws.
> >
> > > > Nando
> >
> > > > On Thu, May 1, 2008 at 9:52 PM, Alan Livie <
> [EMAIL PROTECTED]
> >
> > > > wrote:
> >
> > > > > I'll say again I'm no expert but I'm not sure it's a good
> hierarchy
> > > you're
> > > > > embarking on (but its hard to tell with no details) and think your
> > > > > ContentService should probably have an association to an
> ImageService
> > > > > instead.
> > > > > Then your contentService would just use <cfreturn
> > > > > variables.ImageService.getImageByGallery() />
> > > > > This also means you can use your imageService in other services
> using
> > > the
> > > > > same association.
> >
> > > > > Although the sentence 'an image service IS-A content service'
> sounds
> > > > > correct in the real world it doesn't mean it works at a design
> level.
> > > If
> > > > > your contentService is full of methods that your ImageService can
> use
> > > then
> > > > > perhaps it is a candidate for a parent / child relationship.
> > > > > If ImageService would only ever use one or two of ContntService's
> > > methods
> > > > > then it definately IS NOT a good candidate for a subclass.
> >
> > > > > And thinking along the lines of parents accessing methods in a
> > > subclass I
> > > > > don't think helps either. A good way that inheritance hierarchies
> > > evolve is
> > > > > when you have a class then you realise you need something similar
> but
> > > > > slightly different. Then you realise that some methods in both
> classes
> > > can
> > > > > be shared. Then you refactor by creating a parent class, copying
> the
> > > dupe
> > > > > methods up into it and taking the dupes out of the child classes.
> Add
> > > an
> > > > > extends="path to parent" and you've refactored. And you'll want to
> > > unit test
> > > > > this all the way of course :-)
> >
> > > > > Hope this helps and I'm sure some will disagree with me!
> > > > > ________________________________________
> > > > > From: [email protected] [EMAIL PROTECTED] On Behalf
> Of
> > > > > [EMAIL PROTECTED] [EMAIL PROTECTED]
> > > > > Sent: 01 May 2008 18:27
> > > > > To: CFCDev
> > > > > Subject: [CFCDEV] accessing sub-class methods
> >
> > > > > I need to know if I can access the methods in a child object from
> its
> > > > > parent class and if so, how I might do that.
> >
> > > > > I
> >
> > ...
> >
> > read more ยป
> >
>


-- 

Nando M. Breiter
The CarbonZero Project
CP 234
6934 Bioggio
Switzerland
+41 76 303 4477
[EMAIL PROTECTED]

--~--~---------~--~----~------------~-------~--~----~
You received this message because you are subscribed to the Google Groups 
"CFCDev" group.
To post to this group, send email to [email protected]
To unsubscribe from this group, send email to [EMAIL PROTECTED]
For more options, visit this group at 
http://groups.google.com/group/cfcdev?hl=en
-~----------~----~----~----~------~----~------~--~---

Reply via email to