Beefy Boxes and Bandwidth Generously Provided by pair Networks
"be consistent"
 
PerlMonks  

Base class constructor that blesses into subclass

by mp (Deacon)
on Jul 06, 2002 at 21:07 UTC ( [id://179883]=perlquestion: print w/replies, xml ) Need Help??

mp has asked for the wisdom of the Perl Monks concerning the following question:

Is it generally considered bad practice for a base class constructor to return objects in its derived classes depending on input parameters? If so, what is a preferrable alternative?

Example:

Base class: Sentence
Derived classes: Sentence::Interrogative, Sentence::Declarative, Sentence::Imperative all use Sentence as a base class.

$s = Sentence->new("This is a test."); print ref($s); # Prints Sentence::Declarative $s = Sentence->new("Is this a test?"); print ref($s); # Prints Sentence::Interrogative $s = Sentence->new("Duck!"); print ref($s); # Prints Sentence::Imperative

Replies are listed 'Best First'.
Re: Base class constructor that blesses into subclass
by dws (Chancellor) on Jul 06, 2002 at 21:18 UTC
    Is it generally considered bad practice for a base class constructor to return objects in its derived classes depending on input parameters?

    What you're describing is often called a "Factory Method", though typically it'll be named something other than "new".

    Consider renaming the "constructor", so that an invocation reads something like   $s = Sentence->from_string("This is a test."); or maybe   $s = Sentence->classify("This is a test."); Update: Technically, a factor method is an instance method that can be overridden. Using a class method for this is similar, but this might be closer to a Factory Function, or maybe a Builder pattern.

Re: Base class constructor that blesses into subclass
by Basilides (Friar) on Jul 06, 2002 at 22:45 UTC
    I had a similar thing recently, and funnily enough, in a similar (linguistic) context. One problem comes to my mind: if you return child objects from your parent constructor, the subclasses can have their own methods, but it's not convenient for them to have any object variables, in addition to those they inherit.

    Eg, an abstract Word class may have variables english and greek, but its child class, Noun, may need nom_singular, whereas child class, Verb, may need to be constructed with infinitive.

    Perhaps at the moment you can't imagine, say, your Interrogative and Declarative classes diverging like that, but for the sake of expansion, I'd be cautious of blessing into a subclass.

    I forgot to say, an alternative might be to test the string to decide which kind of subclass you need, then create an instance of that subclass by calling its own constructor, but in each of the constructors for the subclasses, have a call to the parent's constructor (like super in Java). This is what I did, and the PerlMonks very kindly showed my how to do it.

Re: Base class constructor that blesses into subclass
by Jenda (Abbot) on Jul 07, 2002 at 21:26 UTC

    I'd say "As long as the classes support the same set of methods, go ahead."

      Jenda

Re: Base class constructor that blesses into subclass
by John M. Dlugosz (Monsignor) on Jul 08, 2002 at 15:43 UTC
    I use the "Factory method" in C++, and used it a few times last week.

    It seems that you're planning to directly bless the instance into different child classes.

    It would be clean, and quite acceptible, to call the proper constructor for each derived class instead. That is, the factory function figures out which derived class to use, then calls 'new' on it. The factory method never directly creates or blesses anything.

      Thank you. I did as you and Basilides suggested. The factory method determines the class name, then calls the subclass constructor like this:
      return $class_name->new(%args)
      This is cleaner than blessing into the subclass in the "parent". I also more or less incorporated Jenda's suggestion and made the subclasses all support the same methods (except for some accessors that differ across subclasses).

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: perlquestion [id://179883]
Approved by ehdonhon
Front-paged by MeowChow
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others having a coffee break in the Monastery: (1)
As of 2024-04-24 13:35 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found