Re: OO & multiple inheritance.
by davorg (Chancellor) on Nov 18, 2004 at 09:30 UTC
|
You have your inheritance the wrong way round. Cats and dogs are types of animal, so the Cat and Dog classes need to inherit from Animal - not the other way round.
package Animal;
sub new {
my $class = shift;
my $self = {};
bless ($self, $class);
return $self;
}
1;
-------------------------------------------------------------------
package Cat;
use strict;
use Animal;
our @ISA = qw(Animal);
sub speak {
print "meow...\n";
}
1;
-------------------------------------------------------------------
package Dog;
use strict;
use Animal;
our @ISA = qw(Animal);
sub speak {
print "woof...\n";
}
1;
---------------------------------------------------------
#!/usr/bin/perl
use strict;
use warnings;
use Dog;
use Cat;
my $dog = Dog->new();
my $cat = Cat->new();
$dog->speak;
$cat->speak;
I've also removed the "ref($proto) || $proto" cargo-culting from your code. If you want people to be able to call your constructor as an object method as well as a class method then you should probably have another (object method) constructor called "clone" or "copy". It's generally considered bad practice to have one constructor that is used as both.
--
< http://www.dave.org.uk>
"The first rule of Perl club is you do not talk about
Perl club." -- Chip Salzenberg
| [reply] [d/l] |
|
|
Howdy!
I've also removed the "ref($proto) || $proto" cargo-culting from your code. If you want people to be able to call your constructor as an object method as well as a class method then you should probably have another (object method) constructor called "clone" or "copy". It's generally considered bad practice to have one constructor that is used as both.
That paragraph is neeedlessly insulting, especially to someone who is
manifestly new to Perl OO, if not OO in general. Further, it offers no
pointers to more information on why "ref($proto) || $proto" is
a bad thing, and makes an overly broad claim that it is. Without intending
to divert this conversation down that path, I'll note that the question is
not as settled as one would presume from the claim.
| [reply] |
|
|
...is neeedlessly insulting...
Actually, it didn't look insulting to me at all.
I wonder why you aren't giving pointers to the matter, as you critcise their absence. I guess not everyone instantly understand what the both of you are talking about.
I admit I don't do it either, but I know of this thread: ref($proto) - just say no!
...and I have my personal opinion on it too.
Given the opintion expressed in that paragraph is debatable, it's still just one paragraph in a good node providing a complete answer to the OP's question.
Cheerio, Sören
| [reply] |
A reply falls below the community's threshold of quality. You may see it by logging in.
|
Re: OO & multiple inheritance.
by gaal (Parson) on Nov 18, 2004 at 08:58 UTC
|
Method calls in Perl are what is called "virtual" in other languages. If an object is blessed to Dog, and you call $obj->speak(), Perl searches @INC starting from Dog's.
Your constructor is already subclassable -- that's what your blessing to $class achieves -- so instead of calling Animal->new call Dog->new and Cat->new directly, and don't bother with the type; it'll happen automagically.
(You can tell what kind of Animal you have by calling ref $obj on an instance.) | [reply] [d/l] [select] |
|
|
(You can tell what kind of Animal you have by calling ref $obj on an instance.)
But don't do that, as it will break the "null subclass test". Instead, use "isa" or "can" to test inheritance or capability. The code:
if (ref $this eq "Some::Class::Of::Interest") {
...
}
is almost always wrong, and is red-flagged in my code reviews.
| [reply] [d/l] |
|
|
| [reply] [d/l] [select] |
|
|
Yes, you are right, of course.
| [reply] |
Re: OO & multiple inheritance.
by brian_d_foy (Abbot) on Nov 18, 2004 at 19:06 UTC
|
To see this example worked out in detail, check out the Perl Barnyard Object-Oriented tutorial (perlboot), which Randal wrote but failed to mention in his reply. :)
Somehow this is now called the "Beginner's Object Oriented Tutorial", but that's not how it started. I was there when it happened, then someone wussed out on the name.
--
brian d foy <bdfoy@cpan.org>
| [reply] |
Re: OO & multiple inheritance.
by ikegami (Patriarch) on Nov 18, 2004 at 16:23 UTC
|
Like someone already pointed out, you have inheritance backwards. Would you say a "Cat is a type of Animal" or "Animal is a type of Cat"? @ISA is used to express this is a relationship.
Another tip is that you should never have to store something class-specific in a parent class. For example, TYPE should no more in Animal than SOUND. It's better to override a method (class function), like you did with speak.
I also agree with not using ref($proto). It's a legacy from languages which are unable to name their constructors. In Perl, if you need a copy constructor, go ahead and call it copy.
| [reply] [d/l] [select] |