注册 登录  
 加关注
   显示下一条  |  关闭
温馨提示!由于新浪微博认证机制调整,您的新浪微博帐号绑定已过期,请重新绑定!立即重新绑定新浪微博》  |  关闭

Bioinformatics home

 
 
 

日志

 
 

perl OOP面对对象编程研究  

2009-09-07 11:14:14|  分类: Perl |  标签: |举报 |字号 订阅

  下载LOFTER 我的照片书  |


perl面对对象编程:
几句经典的必须记住的话:
一个对象只不过是一个引用...恩,就是引用。
一个类只是一个包 。
一个包当作一个类——通过使用包的子过程来执行类的方法,以及通过使用包的 变量来保存类的全局数据。通常,使用一个模块来保存一个或者更多个类。
一个方法只是一个子过程。

类构造函数
sub new
 { 
   my $type = shift;  #其实shift类名给 $type  
   my %parm = @_;  #传递构造函数
   my $this = {};  #产生一个类
   $this->{"Start"} = $parm{"Start"};  #类属性赋值
   $this->{"End"} = $parm{"End"}; #类属性赋值
   $this->{"Length"} = $parm{"Length"}; #类属性赋值
   $this->{"Sequence"} = $parm{"Sequence"}; #类属性赋值
   $this->{"Average"} = $parm{"Average"}; #类属性赋值    
   bless $this,$type;  # 祝福this类的类型或类名为$type ,就是相当于完成了类的构建,
   return $this; #返回祝福好的类,完成了类构造与初始化
}  
你可以把你的构造器命名为任意的东西。任何碰巧创建和返回一个对象的方法都是实际上的构造器。通常,建议你把你的构造器命名为任何在你解决的问题的环境中有意义的东西。 

类子函数 or 过程
sub xxx
{
  shift; #第一个参数为该类的引用
  my $number=shift;
  return $number*99;
}
1; #一定要有这个1;,这表示最后类引用成功。否则报错。
 
 shift; #第一个参数为该类的引用
 my $type= shift;
 print "\n type is ".$type->add(1,56)."\n";
 
 记住,如果有A类,AA类继承A类,A和AA类中都有add函数。
 如果我们在调用AA类中的函数里面使用
  my $type= shift;
 print "\n type is ".$type->add(1,56)."\n";
 则会调用AA类中的add方法。对于这个我们应该没有异议
 
 有趣的是,如果我们把这两段代码放在A类中
 my $type= shift;
 print "\n type is ".$type->add(1,56)."\n";
 当我们直接调用A类此函数时,这个add方法调用仍然是AA类的add方法
 这些与C#不同,C#中则会去调类本身的add方法。从理论是分析,这是perl OOP的一个缺陷
 
 
 调用类方法:
 1 使用箭头操作符的方法调用
   $mage = Wizard->summon("Gandalf");   # 类方法 记住不用像java, C#等编程语言,没有实例化就可以直接调用类方法。
   $mage->speak("friend");  # 实例方法
  
   甚至你可以用变量当作方法名来调用
   $method = "summon";
   $mage = Wizard->$method("Gandalf");   # 调用Wizard->summon
 
 调用基类方法
 sub add
 {
  my $self=shift;
  my $number1=shift;
  my $number2=shift;
  return $self->SUPER::add($number1,$number2);#调用基类方法 一
     #return Seq->add($number1,$number2);  #调用基类方法 二
 }
 
 类的继承:
 Perl 是这样实现继承的:一个包的 @ISA 数组里的每个元素都保存另外一个包的名字,当缺失方法的时候就搜索这些包。比如,下面的代码把 Horse 类变成 Critter 类的子类。(我们用 our 声明 @ISA,因为它必须是一个打包的变量,而不是用 my 声明的词。)
package Horse;
our @ISA = "Critter";

当你调用了调用者的一个类型为 classname 的方法 methname,Perl 将尝试六种不同的方法来找出所用的子过程():
首先,Perl 在调用者自己的包里查找一个叫 classname::methname 的子过程。如果失败,则进入继承,并且进入步骤 2。
第二步,Perl 通过检查 @classname::ISA 里列出的所有父包,检查从基类继承过来的方法,看看有没有parent::methname子过程。这种搜索是从左向右,递归的,由浅入深进行的。递归保证祖父类,曾祖父类,太祖父类等等类都进入搜索。
如果仍然失败,Perl 就搜索一个叫 UNIVERSAL::methname 的子过程。
这时,Perl 放弃 methname 然后开始查找 AUTOLOAD。首先,它检查叫做 classmane::AUTOLOAD 的子过程。
如果上面的失败,Perl 则搜索所有在 @classname::ISA 里列出的 parent包,寻找任何 parent::AUTOLOAD 子过程。这样的搜索仍然是从左向右,递归的,由浅入深进行的。
最后,Perl 寻找一个叫 UNIVERSAL::AUTOLOAD 的子过程。
Perl 会在找到的第一个子过程处停止并调用该子过程。如果没有找到子过程,则产生一个例外,也是你经常看到的:
   Can't locate object method "methname" via package "classnaem"


附perl完整类、子类、调用代码
package Seq;
require 5.005;
$VERSION = '0.08';
require Exporter;
@ISA = qw( Exporter );
@EXPORT_OK = qw( );
@EXPORT = qw(add,substract,getSeq);

#类构造函数
sub new
 { 
   my $type = shift;  #其实shift类名给 $type  
   my %parm = @_;  #传递构造函数
   my $this = {};  #产生一个类
   $this->{"Start"} = $parm{"Start"};  #类属性赋值
   $this->{"End"} = $parm{"End"}; #类属性赋值
   $this->{"Length"} = $parm{"Length"}; #类属性赋值
   $this->{"Sequence"} = $parm{"Sequence"}; #类属性赋值
   $this->{"Average"} = $parm{"Average"}; #类属性赋值    
   bless $this,$type;  # 祝福this类的类型或类名为$type ,就是相当于完成了类的构建,
   return $this; #返回祝福好的类,完成了类构造与初始化
}

#####类函数
sub add
{
 shift;
 #my ($num1,$num2)=@_;
 my $num1=shift;
    my $num2=shift;
 my $sum;
 $sum=$num1+$num2;
 
 return  $sum;
}

sub substract
{
 shift;
 return $_[0]-$_[1];
}
sub getSeq
{
    my $self=shift;
 #print $VERSION;
 return $self->{"Sequence"};
 #return shift->{"Sequence"};
}

sub xxx
{
 my $type= shift;
 print "\n type is ".$type->add(1,56)."\n";
  my $number=shift;
  return $number*99;
}
1;
#类结束

 

#子类
package SubSeq;
require Seq;
@ISA  = qw( Seq ); #表示继承 Seq类,可以使用它们的函数与变量
#@EXPORT_OK = qw( );
#@EXPORT  = qw(add,substract,getSeq);


 sub muti
 {
  shift;
   my $number=shift;
  return $number*12; 
 }
 
 sub add  #重写子函数
 {
  my $self=shift;
  my $number1=shift;
  my $number2=shift;
  return $self->SUPER::add($number1,$number2);#调用基类方法 一
     #return Seq->add($number1,$number2);  #调用基类方法 二 
 }
1;
#子类结束

 

#调用代码
use SubSeq;
$a = SubSeq->new(
   "Start" => 2,
   "End" => 21,
   "Length" => 20,
   "Sequence" => "AAAAGGCCC",
   "Average" => 5,
   "IfKeep" =>1 );
      
print $a->{"Start"},"\n";
print $a->{'Length'},"\n";
$a->{'Sequence'}="YYYYYYYYYYYYY";
print $a->{'Sequence'},"\n";
print $a->add(88,6),"\n";
print $a->substract(10,2),"\n";
print $a->getSeq(),"\n";
print $a->muti(6);
print "\n\n";
print $a->xxx(6);
print "\n\n";
##调用代码结束

  评论这张
 
阅读(780)| 评论(0)
推荐 转载

历史上的今天

在LOFTER的更多文章

评论

<#--最新日志,群博日志--> <#--推荐日志--> <#--引用记录--> <#--博主推荐--> <#--随机阅读--> <#--首页推荐--> <#--历史上的今天--> <#--被推荐日志--> <#--上一篇,下一篇--> <#-- 热度 --> <#-- 网易新闻广告 --> <#--右边模块结构--> <#--评论模块结构--> <#--引用模块结构--> <#--博主发起的投票-->
 
 
 
 
 
 
 
 
 
 
 
 
 
 

页脚

网易公司版权所有 ©1997-2017