Chinaunix首页 | 论坛 | 博客
  • 博客访问: 1738930
  • 博文数量: 438
  • 博客积分: 9799
  • 博客等级: 中将
  • 技术积分: 6092
  • 用 户 组: 普通用户
  • 注册时间: 2012-03-25 17:25
文章分类

全部博文(438)

文章存档

2019年(1)

2013年(8)

2012年(429)

分类: Python/Ruby

2012-03-26 10:49:02

Perl中的类就是一个pm(Perl Module)文件。创建一个类(myclass.pm):


  1. package Myclass;

  2. 1; # 包的开头标志

  3. sub new {
  4.     my $this = {}; # 创建一个空哈希表
  5.     bless $this; # 把$this与包关联起来
  6.     return $this;
  7. }

  8. sub do {
  9.     $self = shift; # 第一个参数是对象本身
  10.     print "I'm doing ".shift; # 函数调用传入的参数
  11. }

  12. 1; # 包的结束标志

第一行声明包名,也是就类名。包的内容必须用两个“1;”包含,否则不会被包处理。子程序new用来创建对象,一个对象就是通过bless与包关联起来的哈希表。类的成员函数的第一个参数是对象引用。

使用一个类(pl文件和pm文件在同一个文件夹下):


  1. #!/usr/bin/env perl
  2. use myclass; # pm文件名myclass
  3. $pClass = new Myclass; # 类所在的包名Myclass
  4. print "$pClass\n"; # Myclass=HASH(0x9c2ca6c)
  5. $pClass->do("work"); # I'm doing work

  6. $pClass = Myclass->new(); # 另一种创建对象的方式
  7. $pClass->do("nothing");

  8. $pClass = Myclass::new(); # 第三种创建对象的方式
  9. $pClass->do("something");

如果pl文件和pm文件不在同一个文件夹下,比如myclass.pm在一个名叫"pm"的子文件夹下,有两种方式可以引用。第一种用use或require目录::包名的方式:


  1. require pm::myclass; # 相对路径
  2. require ::usr::local::pm::myclass; # 绝对路径
  3. use pm::myclass; # 只可以用相对路径

第二种方式是向@INC数组添加元素,再用require引用:
  1. push(@INC, "pm");
  2. require myclass; # 只能用require,不能用use

Perl use是发生在编译期,而Perl require发生在运行期。

 

构造函数的参数以及成员变量


  1. sub new {
  2.     my $type = shift;
  3.     my %parm = @_; # 构造函数参数
  4.     my $this = {};
  5.     $this->{"Name"} = $parm{"Name"};
  6.     $this->{"Time"} = $parm{"Time"};
  7.     bless $this;
  8.     return $this;
  9. }

  10. sub do {
  11.     $self = shift;
  12.     printf ("%s is doing %s at %s", $self->{"Name"}, shift, $self->{"Time"});
  13. }

用参数构造对象:

  1. $pClass = new Myclass("Name", "Tommy", "Time", "14:00");
  2. $pClass = Myclass->new("Name"=>"Catherine", "Time"=>"12:15")

bless的作用是把一个哈希表与一个类关联起来,这样就可以通过这个哈希表调用类的方法。下面是一个例子:
blue.pm与red.pm:


  1. package Blue;

  2. 1;

  3. sub show { print "It's blue!\n"; }

  4. 1;

  5. package Red;

  6. 1;

  7. sub show { print "It's red!\n"; }

  8. 1;


使用bless来关联某个类:

  1. #!/usr/bin/perl
  2. use pm::red;
  3. use pm::blue;

  4. $color = {};
  5. bless $color, Blue;
  6. $color->show(); # It's blue!
  7. bless $color, Red;
  8. $color->show(); # It's red!


类方法分为静态方法虚方法


  1. sub static {
  2.     my $type = shift; # 类名
  3.     print "static type: $type - args: @_\n";
  4. }

  5. sub virtual {
  6.     my $object = shift; # 对象引用
  7.     print "object ref: $object - args: @_\n";
  8. }

  9. Myclass::static(1, 2, 3); # static type: 1 - args: 2 3 (类名并没有传进去)
  10. Myclass::static 1, 2, 3; # static type: 1 - args: 2 3 (冒号方式调用可以不用括号)
  11. static Myclass(1, 2, 3); # static type: Myclass - args: 1 2 3
  12. Myclass->static(1, 2, 3); # static type: Myclass - args: 1 2 3

  13. $pClass = new Myclass;
  14. $pClass->virtual(1, 2, 3); # object ref: Myclass=HASH(0x9b6c864) - args: 1 2 3


类可以有析构函数


  1. sub DESTROY {
  2.     #$global = @_[0]; # error: DESTROY created new reference to dead object 'Myclass' during global destruction.
  3.     my $self = shift;
  4.     print "$self is destoryed.\n";
  5. }


类可以继承。BaseClass.pm:


  1. package BaseClass;

  2. 1;

  3. sub new {
  4.     my $this = {};
  5.     bless $this;
  6.     return $this;
  7. }
  8.     
  9. sub inBase { print "in base!!\n"; }
  10.     
  11. 1;

  12. DerivedClass.pm:

  13. package DerivedClass;

  14. 1;

  15. require BaseClass;
  16.     
  17. @ISA = qw(BaseClass); # 表明BaseClass是自己的基类,否则不能通过子类调用基类的方法
  18.     
  19. sub new {
  20.     $type = shift;
  21.     $this = new BaseClass;
  22.     bless $this, $type;
  23.     return $this;
  24. }

  25. 1;

调用代码:
  1. push(@INC, "pm");
  2. require DerivedClass;

  3. $pDerived = new DerivedClass;
  4. $pDerived->inBase(); # in base!

继承的方法是虚方法,你可以在子类中覆盖在基类中定义的方法:
DerivedClass.pm:


  1. sub inBase {
  2.     print "in derived class actually!\n";
  3.     $self = shift;
  4.     $self->SUPER::inBase(); # 调用父类的方法。(通过查询@ISA数组)
  5. }

阅读(858) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~