|
正如其他面向对象的语言一样,一个类总有他自己的一套方法,通过这些方法来操作这个类的对象。实际上,类的方法也就是一些子函数,或称为子例程。但是它们和普通的子例程有所不同,类方法总是隐含传递第一个参数,该参数可以是类名,也可能是指向对象的引用。比如,你显式的传递了 3 个函数给某个类方法,但实际上传递过去的却是 4 个。
比如下面我们可以创建一个 House.pm 模块文件(该模块构成如下图所示),该文件中就只有一个包声明。因为包又可称之为类,所以一个这就是一个 House 类。
由上图可以看到,在包中的 3 个子例程new, set_data 和 get_data 就是操作属于该类对象的方法。其中第一个 new 称为构造函数方法,该方法负责定义和创建(构造)指定的对象。当模块使用者调用 new 方法时,就能得到一个指向新建的 House 对象的引用(即 house 对象地址)。在上面说过,类方法总是隐含的传递第一个参数,比如这里的第一句 my $class = shift; 就是将 new 方法所在的类的类名作为第一个参数传递到变量 $class 中。
在上图的 new 中,通过 my $ref = { }; 语句创建了一个指向空的匿名散列的指针,也就是一个没有数据的对象也同时被创建,然后使用 bless 函数将这个对象归入到 House 包中,这样该对象就知道自己所属的类(包)了,因为后续的,我们可以使用后面的两个方法 set_data 和 get_data 来操作这个对象。这里,set_data 方法用来对对象数据进行赋值,而 get_data 方法用来获取对象的属性。
创建一个只有仅含有构造函数的 House.pm 模块:
[code=perl]package House;
sub new {
my $class = shift;
#对象属性,初始化时不给定任何值,可在后续方法中再设定
my $ref = {
"Owner" => undef,
"Price" => undef,
};
#$ref 引用本类的对象,经过bless函数后,$ref可以使用本类中的方法了
bless($ref, $class);
return $ref; #返回引用
}
1; #这个不能漏[/mw_shl_code]
下面使用一个脚本来使用上面的模块:
[code=perl]#!/usr/bin/perl
use House;
#调用构造方法创建对象以及获得对象的引用
my $houseref = House->new();
print "\$houseref in main belongs to class ", ref($houseref), ".\n";[/mw_shl_code]
运行输出:[beyes@beyes simple]$ ./obj.pl
$houseref in main belongs to class House. 在上面代码中,注意调用类方法的方式:类名->方法 。实际上,这种方式会被 Perl 翻译为 $house::new(House); 。
示例模块 2:
[code=perl]
#!/usr/bin/perl
package House;
sub new {
my $class = shift;
my $ref = {}; #匿名且空的散列
bless ($ref); #不加第2个参数则默认使用当前包
return $ref;
}
sub set_owner {
my $self = shift; #方法的第一个参数隐含了类(包)名
print "\$self is a class ", ref($self), " reference.\n";
$self->{"Owner"} = shift; #客户指定的第 1 参数实际上是方法里的第 2 个参数
}
sub display_owner {
my $self = shift; #方法的第一个参数隐含了类(包)名
print $self->{"Owner"}, "\n";
}
1;[/mw_shl_code]
使用模块代码:
[code=perl]#!/usr/bin/perl
use House;
my $house = House->new;
$house->set_owner("Tom Savege");
$house->display_owner;[/mw_shl_code]
运行输出:[beyes@beyes house2]$ ./obj.pl
$self is a class House reference.
Tom Savege 在上面的程序中,构造函数 new 返回的引用赋值给 $house,此后便可以利用该指针来使用类中的方法。
上面的 2 个例子中在调用构造函数时都没有传递参数,实际上这一行为也是可以的。通过给构造函数传递参数,可以在创建对象时定制其内容。比如下面的模块:
[code=perl]package House;
sub new {
my $class = shift;
#用来接收传入的参数
my ($owner, $salary) = @_;
my $ref = {
"Owner" => $owner,
"Price" => $salary,
};
bless($ref, $class);
return $ref;
}
sub display_object {
my $self = shift; #接收对象的引用
while (($key, $value) = each %$self) {
print "$key : $value \n";
}
}
1;
[/mw_shl_code]
应该该模块的脚本:
[code=perl]#!/usr/bin/perl
use House;
my $house1 = House->new("Tom savage", 250000);
my $house2 = House->new("Devin Qun", 55000);
#注意,第一参数默认是对象的引用
$house1->display_object;
$house2->display_object;
print "$house1, $house2\n";[/mw_shl_code]
运行输出:[beyes@beyes 146]$ ./obj.pl
Owner : Tom savage
Price : 250000
Owner : Devin Qun
Price : 55000
House=HASH(0x8c7e830), House=HASH(0x8c7f530) |
本帖子中包含更多资源
您需要 登录 才可以下载或查看,没有帐号?立即注册
x
|