Learning Perl Objects, References amp;amp; Modules [Electronic resources] نسخه متنی

اینجــــا یک کتابخانه دیجیتالی است

با بیش از 100000 منبع الکترونیکی رایگان به زبان فارسی ، عربی و انگلیسی

Learning Perl Objects, References amp;amp; Modules [Electronic resources] - نسخه متنی

Randal L. Schwartz

| نمايش فراداده ، افزودن یک نقد و بررسی
افزودن به کتابخانه شخصی
ارسال به دوستان
جستجو در متن کتاب
بیشتر
تنظیمات قلم

فونت

اندازه قلم

+ - پیش فرض

حالت نمایش

روز نیمروز شب
جستجو در لغت نامه
بیشتر
لیست موضوعات
توضیحات
افزودن یادداشت جدید














10.4 Additional Instance Variables in Subclasses


One of the nice things about
using a hash for a data structure is that derived classes can add
additional instance variables without the superclass needing to know
of their addition. For example, let's derive a
RaceHorse class that is everything a
Horse is but also tracks its win/place/show/lose
standings. The first part of this is trivial:

{ package RaceHorse;
our @ISA = qw(Horse);
...
}

You'll
also want to initialize "no wins of no
races" when you create the
RaceHorse. You do this by extending the
named subroutine and adding four additional fields
(wins, places,
shows, losses, for first-,
second-, and third-place finishes, and none of the above):

{ package RaceHorse;
our @ISA = qw(Horse);
## extend parent constructor:
sub named {
my $self = shift->SUPER::named(@_);
$self->{$_} = 0 for qw(wins places shows losses);
$self;
}
}

Here, you pass all parameters
to the superclass, which should return a fully formed
Horse. However, because you pass
RaceHorse as the class, it'd be
already blessed into the RaceHorse
class.[8]
Next, add the four instance variables that go beyond those defined in
the superclass, setting their initial values to 0. Finally, return
the modified RaceHorse to the caller.

[8] Similar to the way the
Animal constructor creates a
Horse, not an Animal, when
passed Horse as the class.


It's important to note
here that we've actually "opened
the box" a bit while writing this derived class. You
know that the superclass uses a hash reference and that the
superclass hierarchy doesn't use the four names
chosen for a derived class. This is because
RaceHorse will be a
"friend" class (in C++ or Java
terminology), accessing the instance variables directly. If the
maintainer of Horse or Animal
ever changes representation or names of variables, there could be a
collision, which might go undetected except for that important day
when you're showing off your code to the investors.
Things get even more interesting if the hashref is changed to an
arrayref as well.

One way to decouple this
dependency is to use composition rather than inheritance as a way to
create a derived class. In this example, you need to make a
Horse object an instance variable of a
RaceHorse and put the rest of the data in separate
instance variables. You also need to pass any inherited method calls
on the RaceHorse down to the
Horse instance, through delegation. However, even
though Perl can certainly support the needed operations, that
approach is usually slower and more cumbersome. Enough on that for
this discussion,
however.

Next, let's provide some access methods:

{ package RaceHorse;
our @ISA = qw(Horse);
## extend parent constructor:
sub named {
my $self = shift->SUPER::named(@_);
$self->{$_} = 0 for qw(wins places shows losses);
$self;
}
sub won { shift->{wins}++; }
sub placed { shift->{places}++; }
sub showed { shift->{shows}++; }
sub lost { shift->{losses}++; }
sub standings {
my $self = shift;
join ", ", map "$self->{$_} $_", qw(wins places shows losses);
}
}
my $racer = RaceHorse->named("Billy Boy");
# record the outcomes: 3 wins, 1 show, 1 loss
$racer->won;
$racer->won;
$racer->won;
$racer->showed;
$racer->lost;
print $racer->name, " has standings of: ", $racer->standings, ".\n";

This prints:

Billy Boy has standings of: 3 wins, 0 places, 1 shows, 1 losses.
[Billy Boy has died.]
[Billy Boy has gone off to the glue factory.]

Note that we're
still getting the Animal and
Horse destructor. The superclasses are unaware
that we've added four additional elements to the
hash and so, still function as they always have.



/ 199