曲径通幽论坛

 找回密码
 立即注册
搜索
查看: 5510|回复: 0
打印 上一主题 下一主题

[OOP] 构造模块与类的方法

[复制链接]

4917

主题

5879

帖子

3万

积分

GROAD

曲径通幽,安觅芳踪。

Rank: 6Rank: 6

积分
34382
跳转到指定楼层
楼主
发表于 2011-10-29 19:30:05 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
正如其他面向对象的语言一样,一个类总有他自己的一套方法,通过这些方法来操作这个类的对象。实际上,类的方法也就是一些子函数,或称为子例程。但是它们和普通的子例程有所不同,类方法总是隐含传递第一个参数,该参数可以是类名,也可能是指向对象的引用。比如,你显式的传递了 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
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Archiver|曲径通幽 ( 琼ICP备11001422号-1|公安备案:46900502000207 )

GMT+8, 2024-5-6 01:34 , Processed in 0.063325 second(s), 23 queries .

Powered by Discuz! X3.2

© 2001-2013 Comsenz Inc.

快速回复 返回顶部 返回列表