Perl Cd Bookshelf [Electronic resources] نسخه متنی

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

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

Perl Cd Bookshelf [Electronic resources] - نسخه متنی

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

فونت

اندازه قلم

+ - پیش فرض

حالت نمایش

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

13.10. Writing an Inheritable Class


13.10.1. Problem



You''re
not sure whether you''ve designed your class robustly enough to be
inherited.

13.10.2. Solution


Use the "empty subclass test" on your class.

13.10.3. Discussion


Imagine you''ve implemented a class named Person that supplies a
constructor named new, and methods such as
age and name. Here''s the
straightforward implementation:

package Person;
sub new {
my $class = shift;
my $self = { };
return bless $self, $class;
}
sub name {
my $self = shift;
$self->{NAME} = shift if @_;
return $self->{NAME};
}
sub age {
my $self = shift;
$self->{AGE} = shift if @_;
return $self->{AGE};
}

You might use the class in this way:

use Person;
my $dude = Person->new( );
$dude->name("Jason");
$dude->age(23);
printf "%s is age %d.\n", $dude->name, $dude->age;

Now consider another class, the one named Employee:

package Employee;
use Person;
@ISA = ("Person");
1;

There''s not a lot to that one. All it''s doing is loading in class
Person and stating that Employee will inherit any needed methods from
Person. Since Employee has no methods of its own, it will get all of
its methods from Person. We rely upon an Employee to behave just like
a Person.

Setting up an empty class like this is
called the empty base class test; that is, it
creates a derived class that does nothing but inherit from a base
class. If the original base class has been designed properly, then
the new derived class can be used as a drop-in replacement for the
old one. This means you should be able to change just the class name
and everything will still work:

use Employee;
my $empl = Employee->new( );
$empl->name("Jason");
$empl->age(23);
printf "%s is age %d.\n", $empl->name, $empl->age;

By proper design, we mean using only the two-argument form of
bless, avoiding any direct access of class data,
and exporting nothing. In the Person::new( )
function defined previously, we were careful to do these things. We
use some package data in the constructor, but the reference to this
is stored on the object itself. Other methods access package data via
that reference, so we should be okay.


Why did we
say the Person::new
function—is that not actually a method? A
method is just a function that expects its first argument to be a
class name (package) or object (blessed reference).
Person::new is the function that the
Person->new method and the
Employee->new method both end up calling. (See
Table 13-1.) Although method invocation looks a lot
like a function call, they aren''t the same. If you treat them as the
same, very soon you''ll be left with nothing but broken programs.
First, the actual underlying calling conventions are different:
methods get an extra argument. Second, function calls don''t do
inheritance, but methods do.

Table 13-1. Mapping methods to functions















Method call


Resulting function call


Person->new( )


Person::new("Person")


Employee->new( )


Person::new("Employee")

If you got in the habit of calling:

$him = Person::new( );               # WRONG

you''d have a subtle problem, because the function wouldn''t get an
argument of "Person" as it is expecting, and so it couldn''t bless
into the passed-in class. Still worse, you''d probably want to try to
call Employee::new also. But there is no such
function! It''s just an inherited method.

So, don''t call a function when you mean to invoke a method.

13.10.4. See Also


perltoot(1), perlobj(1),
and perlbot(1); Chapter 13 of
Programming Perl; Recipe 13.1; Recipe 13.11

/ 875