一个类只是一个包:
一个类只是一个包:
一个方法只是一个子过程:
12.3 方法调用:
如果一个类调用该方法,那参数就是类的名字。
[root@node01 data01]# cat Horse.pm
package Horse;
sub burn {
my $class=shift;
print "$class=$class
";
my $self={
debug=>"abc"
};
bless $self,$class;
};
1;
[root@node01 data01]# cat t4.pl
use Horse;
use Data::Dumper;
my $r=Horse->burn;
print $r;
print "
";
print Dumper($r);
[root@node01 data01]# perl t4.pl
$class=Horse
Horse=HASH(0x1102160)
$VAR1 = bless( {
'debug' => 'abc'
}, 'Horse' );
[root@node01 data01]#
传的参数是类的名字
[root@node01 data01]# cat Horse.pm
package Horse;
sub burn {
my $class=shift;
print "$class=$class
";
my $self={
debug=>"abc"
};
bless $self,$class;
};
sub kick {
my $self=shift;
my $a=shift;
my $b=shift;
return $a + $b;
};
1;
[root@node01 data01]# cat t4.pl
use Horse;
use Data::Dumper;
my $r=Horse->burn;
print $r;
print "
";
print Dumper($r);
print $r->kick(99,78);
[root@node01 data01]# perl t4.pl
$class=Horse
Horse=HASH(0x21d8160)
$VAR1 = bless( {
'debug' => 'abc'
}, 'Horse' );
$self=Horse=HASH(0x21d8160)
177[root@node01 data01]#
对于一个实例方法,调用者是一个声明对象的引用。
12.3.1 使用箭头操作符的方法调用:
INVOCANT->METHOD(LIST)
INVOCANT->METHOD
而当INVOCANT 是一个包的名字的会后,我们把那个被调用的METHOD看作类方法。
还有一条你必须记住:就是对象同样也知道它们的类
$mage = Wizard->summon("Gandalf"); # 类方法
$mage->speak("friend"); # 实例方法
12.3.2 使用间接对象的方法调用:
第2种风格的方法调用看起来像这样:
METHOD INVOCANT (LIST)
METHOD INVOCANT LIST
METHOD INVOCANT
12.4 构造对象:
所有对象都是引用,但不是所有引用都是对象。
一个引用不会作为对象运转,除非引用它的东西有特殊标记告诉Perl它属于哪个包。
把一个引用和一个包名字标记起来(因此也和包中的类标记起来了,因为一个类就是一个包)的动作被称作bless
你可以把bless 看作把一个引用转换成对象
[root@node01 data01]# cat t4.pl
use Horse;
use Data::Dumper;
my $r=Horse->burn;
print "-----------
";
print ref $r;
[root@node01 data01]# perl t4.pl
$class=Horse
-----------
Horse[root@node01 data01]#
一旦赐福了指示物,对它的引用调用内建的ref函数会返回赐福了的类名字,而不是内建的类型。
12.4.1 可继承构造器:
和所有方法一样,构造器只是一个子过程,但是我们不把它看作一个子过程。
在这个例子里,我们总是把它当作一个方法来调用 ---一个类方法,因为调用者是一个包的名字。
比如,假设我们有一个Sppider类从spider类继承了方法。
特别是,假设Spider类没有自己的spawn方法
12.4.2 初始器:
到目前为止我们的所有构造器都创建了空散列,但是我们没有理由让它们这么空着。
比如,我们可以让构造器接受额外的参数,并且把它们当作键字/数值对
[root@node01 data01]# cat Horse.pm
package Horse;
sub new {
my $class=shift;
my %p=@_;
my $self ={
name=>$p{'name'},
color =>$p{'color'}
};
bless $self,$class;
}
1;
[root@node01 data01]# cat s1.pl
use Horse;
use Data::Dumper;
$steed = Horse->new(name => "shadowfax", color => "white");
print Dumper($steed);
[root@node01 data01]# perl s1.pl
$VAR1 = bless( {
'color' => 'white',
'name' => 'shadowfax'
}, 'Horse' );
这回我们用一个名字叫new 的方法做该类构造器
任何碰巧创建和返回一个对象的方法都是实际上的构造器。
12.5 类继承
从一个类继承另外一个类并不需要给这门语句增加特殊的语法。
PERL 是这样实现继承的:一个包的@ISA 数组里的每个元素都保存另外一个包的名字,当缺失
方法的时候留搜索这些包。
[root@node01 data01]# cat Horse.pm
package Horse;
our @ISA = "Critter";
sub new {
my $class=shift;
my %p=@_;
my $self ={
name=>$p{'name'},
color =>$p{'color'}
};
bless $self,$class;
}
sub funh1 {
my $self=shift;
my $a=shift;
my $b=shift;
return $a + $b;
}
1;
Critter 是一个基类,可以用于继承
假设你的$steed里有一个Horse对象,并且在他上面调用了一个move:
$steed->move(10);
[root@node01 data01]# cat Critter.pm
package Critter;
sub move {
my $self=shift;
my $a=shift;
my $b=shift;
return $a + $b;
};
1;
[root@node01 data01]# cat s2.pl
use Horse;
use Data::Dumper;
$steed = Horse->new(name => "shadowfax", color => "white");
print Dumper($steed);
print $steed->move(2,75);
[root@node01 data01]# perl s2.pl
$VAR1 = bless( {
'name' => 'shadowfax',
'color' => 'white'
}, 'Horse' );
Can't locate object method "move" via package "Horse" at s2.pl line 6.
[root@node01 data01]#
提示找不到方法
[root@node01 data01]# cat s2.pl
use Horse;
use Critter;
use Data::Dumper;
$steed = Horse->new(name => "shadowfax", color => "white");
print Dumper($steed);
print $steed->move(2,75);
[root@node01 data01]# perl s2.pl
$VAR1 = bless( {
'name' => 'shadowfax',
'color' => 'white'
}, 'Horse' );
77[root@node01 data01]#