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

Hi,

I want to inherit only few methods from a parent class in my child class.
My Parent class has almost 100 methods from that I need to inherit oly 10 methods,there are some risks involving inheriting the other methods.
May I know how I can accomplish that in Perl.

Thanks,
Shijumic
  • Comment on Inherit only few methods from a parent class

Replies are listed 'Best First'.
Re: Inherit only few methods from a parent class
by SuicideJunkie (Vicar) on Jul 13, 2009 at 14:37 UTC

    It seems to me that if you want to inherit only some methods from a parent class, you may be inheriting from the wrong parent...

    Perhaps you should split that parent up. The common methods could be moved to a common ancestor, and your current "parent" and "child" would become siblings.

Re: Inherit only few methods from a parent class
by lostjimmy (Chaplain) on Jul 13, 2009 at 15:10 UTC

    It sounds like you're taking the wrong approach. One of the selling points of inheritance is that your child classes behave just like the parent classes (at least interface-wise), and are therefore interchangeable (polymorphism).

    If you're looking to simplify the interface to the base class, I wouldn't use inheritance at all. Make a new class as a wrapper around the more complicated class, sort of like the facade design pattern.

    Example:

    package ComplicatedClass; sub new { my $class = shift; return bless {}, $class; } sub method1 { print "This is method 1\n"; } sub method2 { print "This is method 2\n"; } .. sub method99 { print "This is method 99\n"; } sub method100 { print "This is method 100\n"; } package SimpleClass; sub new { my $class = shift; my $cc = new ComplicatedClass; return bless { cc => $cc }, $class; } sub method1 { my $self = shift; $self->{cc}->method1; } sub method42 { my $self = shift; $self->{cc}->method42; } sub method99 { my $self = shift; $self->{cc}->method99; } package main; my $obj = new SimpleClass; $obj->method1; $obj->method42; $obj->method99; $obj->method2; # Can't locate object method "method2" via package "Sim +pleClass"

      I tried the the approach expalined by lostjimmy. But when ever I instantiate my complicated class,it opens a transaction(in the new()) and half of the methods depends on that transaction, which I is not useful in my simple class.
      Is there any way when I instantiate a complicated/parent class,that the complicated/parent class can detect which simple class is calling them, so that I can add logic to not open the transactions..

        You could simply add a second constructor, in which you can skip opening transactions (e.g. ComplicatedClass::new_no_trans).

        That being said, this design seems like it is going to turn in to a maintenance nightmare.

Re: Inherit only few methods from a parent class
by CountZero (Bishop) on Jul 13, 2009 at 15:59 UTC
    How risky can these methods be since you are aware of these risks? Just say "NO" to these methods (in other words, do not use them) and you should be ok.

    CountZero

    A program should be light and agile, its subroutines connected like a string of pearls. The spirit and intent of the program should be retained throughout. There should be neither too little or too much, neither needless loops nor useless variables, neither lack of structure nor overwhelming rigidity." - The Tao of Programming, 4.1 - Geoffrey James

Re: Inherit only few methods from a parent class
by JavaFan (Canon) on Jul 13, 2009 at 15:12 UTC
    You can't by using a language construct. But since it's Perl, you can do:
    package ChildClass; use ParentClass; our @ISA = qw[ChildClass]; sub risky_method1 {die "You're not allowed to call this"} sub risky_method2 {die "You're not allowed to call this either"}
    Repeat for each method you don't want to inherit.
      Thanks much for everydody's reply. I impliment something like JavaFan recommends and it works..
      Currently I am trying to avoid the following for like 90 methods..
      sub risky_method1 {die "You're not allowed to call this"}
      sub risky_method2 {die "You're not allowed to call this either"}

      How can I impliment that? I heard about closures and AUTOLOAD in perl , Do you guys know which one is best?
      Any examples

      Thanks,
      Shijumic
        AUTOLOAD isn't going to work as AUTOLOAD will only be called if the method cannot be found.

        You could created the methods in a loop from a BEGIN statement. What I probably would do is write a one liner which generates the subs, which I'd then concatenate to the file.

      I don't like that construction. If the "risky" methods are used in the parent class, the inheriting child class may die unexpectedly:

      #!/usr/bin/perl -w use strict; package ParentClass; sub new { my $class=shift; return bless {},$class; } sub run { my $self=shift; $self->hello(); $self->risky(); $self->world(); } sub hello { print "*** Hello "; } sub risky { print "risky "; } sub world { print "world! ***\n"; } package ChildClass; our @ISA=qw(ParentClass); sub risky { die "You're not allowed to call risky()"; } package main; $|=1; print "ParentClass:\n"; my $p=ParentClass->new(); $p->run(); print "ChildClass:\n"; my $c=ChildClass->new(); $c->run();

      The only clean solution is to have a common base class without the "risky" methods:

      #!/usr/bin/perl -w use strict; package BaseClass; sub new { my $class=shift; return bless {},$class; } sub hello { print "*** Hello "; } sub world { print "world! ***\n"; } package FormerParentClass; our @ISA=qw(BaseClass); sub risky { print "risky "; } sub run { my $self=shift; $self->hello(); $self->risky(); $self->world(); } package FormerChildClass; our @ISA=qw(BaseClass); sub run { my $self=shift; $self->hello(); $self->world(); } package main; $|=1; print "FormerParentClass:\n"; my $p=FormerParentClass->new(); $p->run(); print "FormerChildClass:\n"; my $c=FormerChildClass->new(); $c->run();

      Alexander

      --
      Today I will gladly share my knowledge and experience, for there are no sweeter words than "I told you so". ;-)
        If the "risky" methods are used in the parent class, the inheriting child class may die unexpectedly
        I agree with everything above, except the word unexpectedly. Yes, it will die. On purpose. Because the OP does not want those methods be callable. And if the Parent class calls those subs as methods, it's calling them on objects of type Child. Which the OP doesn't want. Hence death.
Re: Inherit only few methods from a parent class
by kennethk (Abbot) on Jul 13, 2009 at 14:38 UTC
    As documented in use, modifying your use statement with an explicit list of routines to import will allow you to control how polluted your name space becomes, i.e.:

    use parentModule qw(func1 func2 func3);

    will import only the methods func1, func2 and func3 from the parent module.

    Update: As JavaFan points out below, I jumped in a little quickly. Please disregard.

      That only handles importing names to namespaces. It has nothing to do (unless you're happening to do "if I call it 'mix-ins' I'm much cooler than when I just call it MI") with inheritance, other than that names of both techniques start with the same letter.