perl模块编程之继承

    技术2025-02-05  21

    一、继承

    对于已经习惯了面向对象编程的人应该不再陌生了。继承是其一个主要的特性,增加代码的重用从而提高软件的性能。

    简单的说模块是包,包是类。在C++中的类中都存在一个构造函数,perl也是(当然也可以没有)。一般的perl模块的构造函数如下

    Sub new{

    My $this={};

    Bless $this;

    Return $this;

    }

    但是如果想这个模块派生出另一个模块,这样就不可以,应该在创建的时候就容许其被继承,就必须保证有不同的类型可以被传入到new函数中来,那就以上构造函数改为

    Sub new{

    $type=shift;

    $class=ref($type)||$type;

    My $this={};

    Bless $this,$class;

    Return $this;

    }

    Bless是可以有两个参数的,第二个可选的,如果没有写第二个参数,就是和本模块相bless,写了,就是和已写的类型相bless。可以多次bless一个引用对象,然而,新的将被bless的类必然把对象已被bless的引用去掉,就像在C中把一块内存赋给一指针,再把另一块内存赋给同一个指针,而没有释放前一块内存。记住,一个perl对象每一时刻只能属于一个类。

    Perl类的方法只不过是一个Perl子程序而已,称之为成员函数。Perl的方法的定义不提供任何特殊语法,但规定方法的第一个参数为对象或其被引用的包。Perl有两种方法:静态方法和虚方法。

    静态方法

    静态方法第一个为类的名称,即为模块名称,方法处理第一个参数的方式决定了是静态还是虚的。静态的方法一般会忽略第一个参数,方法知道是属于那个类,如下

    Sub dosomething{

    My ($modulename模块名称,$p1,…)=@_;

    或是对象的引用

    Sub dosomething{

    $self=shift;

    $self->{};

    $self->funname();

    Return $self;

    }

    我公司的基本是用这种。

    虚方法:

    虚方法通常首先把第一个参数shift到变量selfthis中,然后将该值作普通的引用使用。

    1. sub nameLister {2.     my $this = shift;3.     my ($keys ,$value );4.     while (($key, $value) = each (%$this)) {5.         print "/t$key is $value./n";6.     }7. }

    Perl类的继承是通过@ISA数组实现的。@ISA数组不需要在任何包中定义,然而,一旦它被定义,Perl就把它看作目录名的特殊数组。它与@INC数组类似,@INC是包含文件的寻找路径。@ISA数组含有类()名,当一个方法在当前包中未找到时就到@ISA中的包去寻找。@ISA中含有当前类继承的基类名。

    类中调用的所有方法必须属于同一个类或@ISA数组定义的基类。如果一个方法在@ISA数组中未找到,Perl就到AUTOLOAD()子程序中寻找,这个可选的子程序在当前包中用sub定义。若使用AUTOLOAD子程序,必须用use Autoload;语句调用autoload.pm包。AUTOLOAD子程序尝试从已安装的Perl库中装载调用的方法。如果AUTOLOAD也失败了,Perl再到UNIVERSAL类做最后一次尝试,如果仍失败,Perl就生成关于该无法解析函数的错误。

    下面是一个例子

    package Employee;

    ###########################

    #this class is father class

    #is my test pro

    ###########################

    use DDate;

    ###########################

    #构造函数

    ###########################

    sub new

    {

          my $type=shift;

      #ref函数是返回参数是对什么对象的引用

      #$class是对象的类型

          my $class=ref($type)||$type;

          my $hireDate=new DDate;

          my $self={firstname=>undef,

                                      lastname=>undef,

                                hireday=>$hireDate};

          bless($self,$class);

          return $self;

         

    }

     

    sub firstname

    {

          my $s=shift;

          ##就是带参数,参数是firstname

          $s->{firstname}=shift() if(@_);

          return $s->{firstname};

    }

     

    sub lasttname

    {

          my $s=shift;

          ##就是带参数,参数是firstname

          $s->{lastname}=shift() if(@_);

          return $s->{lastname};

    }

     

    sub hireday

    {

          my $s=shift();

          if(@_)

          {

        $s->{hireday}->setdate(@_);

        }else{

             $s->{hireday}->myprint();

        }

    }

    return 1;

     

    子类

    package Hourly;

    use Employee;

    our @ISA=("Employee");#our的作用就是全局化Employee

    #Perl类的继承是通过@ISA数组实现的

    #@ISA数组不需要在任何包定义,但是一旦它出现,perl在解释的时候就会把它看成目录#名的特殊数组。这与#@INC数组相似,@INC是包含文件的寻找路径。@ISA数组包有类#型名称。当一个方法在当前包中未找到时就到#@ISA中的包中去寻找,@ISA就包涵了基#类的名称,调用的方法是同一类或者包含于@ISA中,如果一个方法在数组无法找到,#perl就会到AUTOLOAD子程序寻找,要使用AUTOLOAD,必须显示的调用use Autoload#如果AUTOLOAD也失败了,Perl再到UNIVERSAL类做最后一次尝试,如果仍失败,Perl        就生成关于该无法解析函数的错误。就是在构造函数的时候,有所不同,在构造函数中要构#造基类的,并把返回的#引用和子类的类型相绑定

    sub new

    {

          my $c=shift();

          my $t=ref($c)||$c;

          my $s=$t->SUPER::new();

    ###这样就好理解了,就把Hourly类型作为一个参数传个基类Employee

    #####这样在基类的构造函数中,bless就把哈希的引用和这个类型相关联

          #就是要把子类的类型和基类的哈希绑定

          $s->{rate}=undef;

          bless($s,$t);

          return $s;

    }

    sub rate

    {

          my $s=shift();

          $s->{rate}=shift if(@_);

      return $s->{rate};

    }

    return 1;

    ###############################################################

    #调用程序了

    ###############################################################

    #!/usr/bin/perl

    use Employee;

    use Hourly;

    my $work=new Employee;

    $work->firstname("shi");

    $work->lasttname("xiyun");

    $work->hireday(1,25,1984);

    print $work->firstname()." ". $work->lasttname()."/n";

    $work->hireday();

     

    my $w=new Hourly;

    $w->firstname("Li");

    $w->lasttname("weijiao");

    $w->hireday(1,25,1985);

    $w->rate(8.5);

    print $w->firstname()." ". $w->lasttname()."/n";

    $w->hireday();

    print $w->rate()."/n";

    最新回复(0)