12.5.2 访问被覆盖的方法
当一个类定义一个方法,那么该子过程覆盖任意基类中同名的方法。
想象一下你有一个Mule(骡)对象(它是从Horse(马)类和Donkey(驴)类衍生而来的)
$stallion = Horse->new(gender => "male"); 男性
$molly = Mule->new(gender => "female"); 女性
$colt = $molly->breed($stallion);
这就是SUPER 伪类提供便利的地方,它令你能够调用一个覆盖了的基类方法,而不用声明哪个类定义了该方法。
[root@node01 aaa]# 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;
Horse 类继承了Critter 类
[root@node01 aaa]# 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@node01 aaa]# cat a1.pl
use Horse;
use Data::Dumper;
$steed = Horse->new(color => "dun");
print $steed->kick(12,4);
print "
";
[root@node01 aaa]# perl a1.pl
69
此时调用了Critter.pm 类的kick 方法:
[root@node01 aaa]# cat Critter.pm
package Critter;
our @ISA = "Mule";
require Mule;
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;
让 Critter 继承Mule 类
[root@node01 aaa]# cat Mule.pm
package Mule;
sub kick {
my $self=shift;
my $a=shift;
my $b=shift;
return $a * $b +66;
}
1;
[root@node01 aaa]# perl a1.pl
69
修改
[root@node01 aaa]# cat Critter.pm
package Critter;
our @ISA = "Mule";
require Mule;
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;
$self->SUPER::kick(@_);
};
1;
[root@node01 aaa]# cat a1.pl
use Horse;
use Data::Dumper;
$steed = Horse->new(color => "dun");
print $steed->kick(12,4);
print "
";
[root@node01 aaa]# perl a1.pl
114
当一个类定义一个方法,那么该子过程覆盖任意基类中同名的方法:
[root@node01 111]# 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;
my $a=shift;
my $b=shift;
return $a * $b;
};
1;
[root@node01 111]# cat Critter.pm
package Critter;
our @ISA = "Mule";
require Mule;
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 +5;
};
1;
[root@node01 111]# cat a1.pl
use Horse;
use Data::Dumper;
$steed = Horse->new(color => "dun");
print $steed->kick(12,4);
print "
";
[root@node01 111]# perl a1.pl
48
此时没有去访问基类的方法:
Mule (骡)
类的设计者通过给 Mule(骡)类写自己的 breed 方法覆盖了那些父类的 breed 方法。
这这意味着下面的交叉引用可能不能正确工作:
$stallion = Horse->new(gender => "male"); 男性
$molly = Mule->new(gender => "female"); 女性
$colt = $molly->breed($stallion);