十、继承
类方法通过@ISA数组继承,变量的继承必须明确设定。下例创建两个类Bean.pm和Coffee.pm,其中Coffee.pm继承Bean.pm的一些功能。此例演示如何从基类(或称超类)继承实例变量,其方法为调用基类的构造函数并把自己的实例变量加到新对象中。
Bean.pm代码如下:
package Bean; require Exporter; @ISA = qw(Exporter); @EXPORT = qw(setBeanType); sub new { my $type = shift; my $this = {}; $this->{"Bean"} = "Colombian"; bless $this, $type; return $this; } # # This subroutine sets the class name sub setBeanType{ my ($class, $name) = @_; $class->{"Bean"} = $name; print "Set bean to $name n"; }
此类中,用$this变量设置一个匿名哈希表,将"Bean"类型设为"Colombian"。方法setBeanType()用于改变"Bean"类型,它使用$class引用获得对对象哈希表的访问。
Coffee.pm代码如下:
1 # 2 # The Coffee.pm file to illustrate inheritance. 3 # 4 package Coffee; 5 require Exporter; 6 require Bean; 7 @ISA = qw(Exporter, Bean); 8 @EXPORT = qw(setImports, declareMain, closeMain); 9 # 10 # set item 11 # 12 sub setCoffeeType{ 13 my ($class,$name) = @_; 14 $class->{"Coffee"} = $name; 15 print "Set coffee type to $name n"; 16 } 17 # 18 # constructor 19 # 20 sub new { 21 my $type = shift; 22 my $this = Bean->new(); ##### <- LOOK HERE!!! #### 23 $this->{"Coffee"} = "Instant"; # unless told otherwise 24 bless $this, $type; 25 return $this; 26 } 27 1;
第6行的require Bean;语句包含了Bean.pm文件和所有相关函数,方法setCoffeeType()用于设置局域变量$class->{"Coffee"}的值。在构造函数new()中,$this指向Bean.pm返回的匿名哈希表的指针,而不是在本地创建一个,下面两个语句分别为创建不同的哈希表从而与Bean.pm构造函数创建的哈希表无关的情况和继承的情况:
my $this = {}; #非继承
my $this = $theSuperClass->new(); #继承
下面代码演示如何调用继承的方法:
1 #!/usr/bin/perl 2 push (@INC,"pwd"); 3 use Coffee; 4 $cup = new Coffee; 5 print "n -------------------- Initial values ------------ n"; 6 print "Coffee: $cup->{"Coffee"} n"; 7 print "Bean: $cup->{"Bean"} n"; 8 print "n -------------------- Change Bean Type ---------- n"; 9 $cup->setBeanType("Mixed"); 10 print "Bean Type is now $cup->{"Bean"} n"; 11 print "n ------------------ Change Coffee Type ---------- n"; 12 $cup->setCoffeeType("Instant"); 13 print "Type of coffee: $cup->{"Coffee"} n";
该代码的结果输出如下:
-------------------- Initial values ------------
Coffee: Instant
Bean: Colombian
-------------------- Change Bean Type ----------
Set bean to Mixed
Bean Type is now Mixed
------------------ Change Coffee Type ----------
Set coffee type to Instant
Type of coffee: Instant
上述代码中,先输出对象创建时哈希表中索引为"Bean"和"Coffee"的值,然后调用各成员函数改变值后再输出。
方法可以有多个参数,现在向Coffee.pm模块增加函数makeCup(),代码如下:
sub makeCup { my ($class, $cream, $sugar, $dope) = @_; print "n================================== n"; print "Making a cup n"; print "Add cream n" if ($cream); print "Add $sugar sugar cubesn" if ($sugar); print "Making some really addictive coffee ;-) n" if ($dope); print "================================== n"; }
此函数可有三个参数,不同数目、值的参数产生不同的结果,例如:
1 #!/usr/bin/perl 2 push (@INC,"pwd"); 3 use Coffee; 4 $cup = new Coffee; 5 # 6 # With no parameters 7 # 8 print "n Calling with no parameters: n"; 9 $cup->makeCup; 10 # 11 # With one parameter 12 # 13 print "n Calling with one parameter: n"; 14 $cup->makeCup("1"); 15 # 16 # With two parameters 17 # 18 print "n Calling with two parameters: n"; 19 $cup->makeCup(1,"2"); 20 # 21 # With all three parameters 22 # 23 print "n Calling with three parameters: n"; 24 $cup->makeCup("1",3,"1");
其结果输出如下:
Calling with no parameters:
==================================
Making a cup
==================================
Calling with one parameter:
==================================
Making a cup
Add cream
==================================
Calling with two parameters:
==================================
Making a cup
Add cream
Add 2 sugar cubes
==================================
Calling with three parameters:
==================================
Making a cup
Add cream
Add 3 sugar cubes
Making some really addictive coffee ;-)
==================================
在此例中,函数makeCup()的参数既可为字符串也可为整数,处理结果相同,你也可以把这两种类型的数据处理区分开。在对参数的处理中,可以设置缺省的值,也可以根据实际输入参数值的个数给予不同处理。