对象(下):
如果 @ISA 包含多于一个包的名字,包的搜索都是从左向右的顺序进行的。这些搜索是由
浅入深的,因此,如果你有一个 Mule 类有象下面这样的继承关系:
因为一个 BEGIN 块立即就执行了,所以它甚至可以在其他文件编译前把子过程声明, 定义以及输入等抓过来。这
些动作可能改变编译器对当前文件其他部分分析的结果, 特别是在你输入了子过程定义的情况下。至少,声明一个
子过程就把它当作一个列表 操作符使用,这样就令圆括号是可选的。如果输入的子过程定义了原型,那么调用它
的时候就会当作内建函数分析,甚至覆盖同名的内建函数,这样就可以给它们不同的 语意。use 声明就是一个带有
目的的 BEGIN 块声明。
访问被覆盖的方法:
[root@wx03 5]# cat a5.pl
END {print cccccccccccc."\n"};
print "aaaaaaaaaaaaa\n";
BEGIN {print bbbbbbbbbbbbbb."\n"};
[root@wx03 5]# perl a5.pl
bbbbbbbbbbbbbb
aaaaaaaaaaaaa
cccccccccccc
根据结果,我们得出,BEGIN是在Perl语言运行最开始运行的块,END是在Perl语言运行最后运行的块,并注意BEGIN和END必须是大写的。
有时候, 你希望一个衍生类的方法表现得象基类中的某些方法的封装器。
这就是 SUPER 伪类提供便利的地方。它令你能够调用一个覆盖了的基类方法,而不用声
明是哪个类定义了该方法。
访问被覆盖的方法:
[root@wx03 5]# cat Critter.pm
package Critter;
sub new {
my $self = {};
my $invocant = shift;
my $class = ref($invocant) || $invocant;
my ($name)=@_;
my $self = {
"name" =>$name
};
bless $self, $class; # Use class name to bless() reference
return $self;
};
sub sum2 {
$self=shift;
my $a=shift;
my $b=shift;
return $a + $b;
};
sub fun1 {
$self=shift;
my $a=shift;
my $b=shift;
return $a / $b;
}
sub kick {
my $self=shift;
my $a=shift;
my $b=shift;
return $a / $b +66;
}
1;
[root@wx03 5]# cat a6.pl
use Horse;
use Data::Dumper;
$steed = Horse->new(color => "dun");
print $steed->kick(33,4);
print "\n";
use base qw(Critter);
require Critter;
print $steed->SUPER::kick(33,4);
print "\n";
[root@wx03 5]# perl a6.pl
132
74.25
/********************
[root@wx03 5]# cat Horse.pm
package Horse;
our @ISA = "Critter";
require Critter;
sub new {
my $invocant = shift;
my $class = ref($invocant) || $invocant;
my $self = {
color => "bay",
legs => 4,
owner => undef,
@_, # 覆盖以前的属性
};
return bless $self, $class;
#return $self;
};
sub sum1 {
$self=shift;
my $a=shift;
my $b=shift;
return $a + $b + 7;
};
sub kick {
my $self=shift;
$self->SUPER::kick(@_);
};
1;
[root@wx03 5]# cat Critter.pm
package Critter;
sub new {
my $self = {};
my $invocant = shift;
my $class = ref($invocant) || $invocant;
my ($name)=@_;
my $self = {
"name" =>$name
};
bless $self, $class; # Use class name to bless() reference
return $self;
};
sub sum2 {
$self=shift;
my $a=shift;
my $b=shift;
return $a + $b;
};
sub fun1 {
$self=shift;
my $a=shift;
my $b=shift;
return $a / $b;
}
sub kick {
my $self=shift;
my $a=shift;
my $b=shift;
return $a / $b +66;
}
1;
[root@wx03 5]# cat a6.pl
use Horse;
use Data::Dumper;
$steed = Horse->new(color => "dun");
print $steed->kick(12,4);
print "\n";
[root@wx03 5]# perl a6.pl
69
UNIVERSAL :最终的祖先类:
这个包从来不会在
@ISA 中出现,但如果查找 @ISA 失败总是要查找它。你可以把 UNIVERSAL 看作最终
的祖先,所有类都隐含地从它衍生而来。
INVOCANT->isa(CLASS)
如果 INVOCANT 的类是 CLASS 或者任何从 CLASS 继承来的,isa 方法返回真。
[root@wx03 5]# cat a7.pl
use Horse;
use Data::Dumper;
$steed = Horse->new(color => "dun");
print $steed->isa(Horse);
print "\n";
print $steed->isa(Critter);
print "\n";
print $steed->isa(test);
print "\n";
[root@wx03 5]# perl a7.pl
1
1
[root@wx03 5]#
$steed的类是Horse 或者从Horse继承而来的((Critter);
判断是否是HASH类型:
[root@wx03 5]# cat a7.pl
use Horse;
use Data::Dumper;
$steed = Horse->new(color => "dun");
print $steed->isa(Horse);
print "\n";
print $steed->isa(Critter);
print "\n";
print UNIVERSAL::isa($steed,'HASH');
print "\n";
[root@wx03 5]# perl a7.pl
1
1
1
判断方法是否存在:
[root@wx03 5]# cat a8.pl
use Horse;
use Data::Dumper;
$steed = Horse->new(color => "dun");
print $steed->can(sum1);
print "\n";
print $steed->can(sumxx);
print "\n";
[root@wx03 5]# perl a8.pl
CODE(0x28f89d0)
[root@wx03 5]#
我们可以用这个方法实现条件调用——只有方法存在才调用:
$obj->snarl if $obj->can("snarl");
方法自动装载:
[root@wx03 5]# cat Horse.pm
package Horse;
our @ISA = "Critter";
require Critter;
sub new {
my $invocant = shift;
my $class = ref($invocant) || $invocant;
my $self = {
color => "bay",
legs => 4,
owner => undef,
@_, # 覆盖以前的属性
};
return bless $self, $class;
#return $self;
};
sub sum1 {
$self=shift;
my $a=shift;
my $b=shift;
return $a + $b + 7;
};
sub kick {
my $self=shift;
$self->SUPER::kick(@_);
};
%h1=(a=>1);
sub AUTOLOAD {
return testdadadak888 ;
};
1;
[root@wx03 5]# cat a8.pl
use Horse;
use Data::Dumper;
$steed = Horse->new(color => "dun");
print $steed->dahda8da;
print "\n";
[root@wx03 5]# perl a8.pl
testdadadak888
[root@wx03 5]#
私有方法:
实例析构器;
管理实例数据:
比如,如果你希望一个叫 $city 的对象有一个数据
域名字叫 elevation,你可以简单地 $city->{elevation} 这样访问它。可以不用声明。
方法的封装会为你做这些。
大多数类都把它们的对象的属性保存在一个匿名散列表
里。对象的实例数据保存在这个散列表里,这个散列表也是该对象自己的小名字空间,用以
划分哪个类对该对象进行了哪些操作。
use fields 定义的域:
对象不一定要用匿名散列来实现。任何引用都可以。比如,如果你使用一个匿名数组,你可
以这样设置一个构造器;
用 Class::Struct 生成类:
使用 Autoloading (自动装载)生成指示器:
转载于:https://www.cnblogs.com/zhaoyangjian724/p/6199951.html