Perl中的类就是一个pm(Perl Module)文件。创建一个类(myclass.pm):
- package Myclass;
- 1; # 包的开头标志
- sub new {
- my $this = {}; # 创建一个空哈希表
- bless $this; # 把$this与包关联起来
- return $this;
- }
- sub do {
- $self = shift; # 第一个参数是对象本身
- print "I'm doing ".shift; # 函数调用传入的参数
- }
- 1; # 包的结束标志
第一行声明包名,也是就类名。包的内容必须用两个“1;”包含,否则不会被包处理。子程序new用来创建对象,一个对象就是通过bless与包关联起来的哈希表。类的成员函数的第一个参数是对象引用。
使用一个类(pl文件和pm文件在同一个文件夹下):
- #!/usr/bin/env perl
- use myclass; # pm文件名myclass
- $pClass = new Myclass; # 类所在的包名Myclass
- print "$pClass\n"; # Myclass=HASH(0x9c2ca6c)
- $pClass->do("work"); # I'm doing work
- $pClass = Myclass->new(); # 另一种创建对象的方式
- $pClass->do("nothing");
- $pClass = Myclass::new(); # 第三种创建对象的方式
- $pClass->do("something");
如果pl文件和pm文件不在同一个文件夹下,比如myclass.pm在一个名叫"pm"的子文件夹下,有两种方式可以引用。第一种用use或require目录::包名的方式:
- require pm::myclass; # 相对路径
- require ::usr::local::pm::myclass; # 绝对路径
- use pm::myclass; # 只可以用相对路径
第二种方式是向@INC数组添加元素,再用require引用:
- push(@INC, "pm");
- require myclass; # 只能用require,不能用use
Perl use是发生在编译期,而Perl require发生在运行期。
构造函数的参数以及成员变量:
- sub new {
- my $type = shift;
- my %parm = @_; # 构造函数参数
- my $this = {};
- $this->{"Name"} = $parm{"Name"};
- $this->{"Time"} = $parm{"Time"};
- bless $this;
- return $this;
- }
- sub do {
- $self = shift;
- printf ("%s is doing %s at %s", $self->{"Name"}, shift, $self->{"Time"});
- }
用参数构造对象:
- $pClass = new Myclass("Name", "Tommy", "Time", "14:00");
- $pClass = Myclass->new("Name"=>"Catherine", "Time"=>"12:15")
bless的作用是把一个哈希表与一个类关联起来,这样就可以通过这个哈希表调用类的方法。下面是一个例子:
blue.pm与red.pm:
- package Blue;
- 1;
- sub show { print "It's blue!\n"; }
- 1;
- package Red;
- 1;
- sub show { print "It's red!\n"; }
- 1;
使用bless来关联某个类:
- #!/usr/bin/perl
- use pm::red;
- use pm::blue;
- $color = {};
- bless $color, Blue;
- $color->show(); # It's blue!
- bless $color, Red;
- $color->show(); # It's red!
类方法分为静态方法和虚方法:
- sub static {
- my $type = shift; # 类名
- print "static type: $type - args: @_\n";
- }
- sub virtual {
- my $object = shift; # 对象引用
- print "object ref: $object - args: @_\n";
- }
- Myclass::static(1, 2, 3); # static type: 1 - args: 2 3 (类名并没有传进去)
- Myclass::static 1, 2, 3; # static type: 1 - args: 2 3 (冒号方式调用可以不用括号)
- static Myclass(1, 2, 3); # static type: Myclass - args: 1 2 3
- Myclass->static(1, 2, 3); # static type: Myclass - args: 1 2 3
- $pClass = new Myclass;
- $pClass->virtual(1, 2, 3); # object ref: Myclass=HASH(0x9b6c864) - args: 1 2 3
类可以有析构函数:
- sub DESTROY {
- #$global = @_[0]; # error: DESTROY created new reference to dead object 'Myclass' during global destruction.
- my $self = shift;
- print "$self is destoryed.\n";
- }
类可以继承。BaseClass.pm:
- package BaseClass;
- 1;
- sub new {
- my $this = {};
- bless $this;
- return $this;
- }
-
- sub inBase { print "in base!!\n"; }
-
- 1;
- DerivedClass.pm:
- package DerivedClass;
- 1;
- require BaseClass;
-
- @ISA = qw(BaseClass); # 表明BaseClass是自己的基类,否则不能通过子类调用基类的方法
-
- sub new {
- $type = shift;
- $this = new BaseClass;
- bless $this, $type;
- return $this;
- }
- 1;
调用代码:
- push(@INC, "pm");
- require DerivedClass;
- $pDerived = new DerivedClass;
- $pDerived->inBase(); # in base!
继承的方法是虚方法,你可以在子类中覆盖在基类中定义的方法:
DerivedClass.pm:
- sub inBase {
- print "in derived class actually!\n";
- $self = shift;
- $self->SUPER::inBase(); # 调用父类的方法。(通过查询@ISA数组)
- }
阅读(907) | 评论(0) | 转发(0) |