⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 perl 语言-perl 中文教程(第十三章).htm

📁 perl的中文教程
💻 HTM
📖 第 1 页 / 共 3 页
字号:
      <BLOCKQUOTE>
        <P>/*<BR>** Created by Cocoa.pm<BR>** Use at own risk <BR>*/<BR>import 
        java.io.InputStream;<BR>import java.net.*;<BR><BR>public class Msg 
        extends java.applet.Applet implements Runnable {<BR>} </P></BLOCKQUOTE>
      <P>&nbsp;&nbsp;&nbsp;&nbsp;注意:如果用-&gt;操作符调用方法(也叫间接调用),参数必须用括号括起来,如:$cup-&gt;setImports( 
      'java.io.InputStream', 'java.net.*');而双冒号调用如:Cocoa::setImports($cup, 
      'java.io.InputStream', 'java.net.*');也可去掉括号写成:Cocoa::setImports $cup, 
      'java.io.InputStream', 'java.net.*' ;<BR><BR><A 
      name=8>八、重载</A><BR>&nbsp;&nbsp;&nbsp;&nbsp;有时需要指定使用哪个类的方法,如两个不同的类有同名方法的时候。假设类Espresso和Qava都定义了方法grind,可以用::操作符指定使用Qava的方法:<BR>&nbsp;&nbsp;&nbsp;&nbsp;$mess 
      = 
      Qava::grind("whole","lotta","bags");<BR>&nbsp;&nbsp;&nbsp;&nbsp;Qava::grind($mess, 
      "whole","lotta","bags");<BR>&nbsp;&nbsp;&nbsp;&nbsp;可以根据程序的运行情况来选择使用哪个类的方法,这可以通过使用符号引用去调用来实现:<BR>&nbsp;&nbsp;&nbsp;&nbsp;$method 
      = $local ? "Qava::" : 
      "Espresso::";<BR>&nbsp;&nbsp;&nbsp;&nbsp;$cup-&gt;{$method}grind(@args);<BR><BR><A 
      name=9>九、析构函数</A><BR>&nbsp;&nbsp;&nbsp;&nbsp;Perl跟踪对象的链接数目,当某对象的最后一个应用释放到内存池时,该对象就自动销毁。对象的析构发生在代码停止后,脚本将要结束时。对于全局变量而言,析构发生在最后一行代码运行之后。<BR>&nbsp;&nbsp;&nbsp;&nbsp;如果你想在对象被释放之前获取控制权,可以定义DESTROY()方法。DESTROY()在对象将释放前被调用,使你可以做一些清理工作。DESTROY()函数不自动调用其它DESTROY()函数,Perl不做内置的析构工作。如果构造函数从基类多次bless,DESTROY()可能需要调用其它类的DESTROY()函数。当一个对象被释放时,其内含的所有对象引用自动释放、销毁。<BR>&nbsp;&nbsp;&nbsp;&nbsp;一般来说,不需要定义DESTROY()函数,如果需要,其形式如下:<BR></P>
      <BLOCKQUOTE>
        <P>sub DESTROY {<BR>#<BR># Add code here.<BR>#<BR>} </P></BLOCKQUOTE>
      <P>&nbsp;&nbsp;&nbsp;&nbsp;因为多种目的,Perl使用了简单的、基于引用的垃圾回收系统。任何对象的引用数目必须大于零,否则该对象的内存就被释放。当程序退出时,Perl的一个彻底的查找并销毁函数进行垃圾回收,进程中的一切被简单地删除。在UNIX类的系统中,这像是多余的,但在内嵌式系统或多线程环境中这确实很必要。<BR><A 
      name=10>十、继承</A><BR>&nbsp;&nbsp;&nbsp;&nbsp;类方法通过@ISA数组继承,变量的继承必须明确设定。下例创建两个类Bean.pm和Coffee.pm,其中Coffee.pm继承Bean.pm的一些功能。此例演示如何从基类(或称超类)继承实例变量,其方法为调用基类的构造函数并把自己的实例变量加到新对象中。<BR>&nbsp;&nbsp;&nbsp;&nbsp;Bean.pm代码如下:<BR></P>
      <BLOCKQUOTE>
        <P>package Bean;<BR>require Exporter;<BR>@ISA = qw(Exporter);<BR>@EXPORT 
        = qw(setBeanType);<BR><BR>sub new {<BR>&nbsp; my $type = 
        shift;<BR>&nbsp; my $this = {};<BR>&nbsp; $this-&gt;{'Bean'} = 
        'Colombian';<BR>&nbsp; bless $this, $type;<BR>&nbsp; return 
        $this;<BR>}<BR><BR>#<BR># This subroutine sets the class name<BR>sub 
        setBeanType{<BR>&nbsp; my ($class, $name) = @_;<BR>&nbsp; 
        $class-&gt;{'Bean'} = $name;<BR>&nbsp; print "Set bean to $name 
        \n";<BR>}<BR>1; </P></BLOCKQUOTE>
      <P>&nbsp;&nbsp;&nbsp;&nbsp;此类中,用$this变量设置一个匿名哈希表,将'Bean'类型设为'Colombian'。方法setBeanType()用于改变'Bean'类型,它使用$class引用获得对对象哈希表的访问。<BR>&nbsp;&nbsp;&nbsp;&nbsp;Coffee.pm代码如下:<BR></P>
      <BLOCKQUOTE>
        <P>1&nbsp; #<BR>2&nbsp; # The Coffee.pm file to illustrate 
        inheritance.<BR>3&nbsp; #<BR>4&nbsp; package Coffee;<BR>5&nbsp; require 
        Exporter;<BR>6&nbsp; require Bean;<BR>7&nbsp; @ISA = qw(Exporter, 
        Bean);<BR>8&nbsp; @EXPORT = qw(setImports, declareMain, 
        closeMain);<BR>9&nbsp; #<BR>10 # set item<BR>11 #<BR>12 sub 
        setCoffeeType{<BR>13 &nbsp; my ($class,$name) = @_;<BR>14 &nbsp; 
        $class-&gt;{'Coffee'} = $name;<BR>15 &nbsp; print "Set coffee type to 
        $name \n";<BR>16 &nbsp; }<BR>17 #<BR>18 # constructor<BR>19 #<BR>20 sub 
        new {<BR>21 &nbsp; my $type = shift;<BR>22 &nbsp; my $this = 
        Bean-&gt;new(); ##### &lt;- LOOK HERE!!! ####<BR>23 &nbsp; 
        $this-&gt;{'Coffee'} = 'Instant'; # unless told otherwise<BR>24 &nbsp; 
        bless $this, $type;<BR>25 &nbsp; return $this;<BR>26 &nbsp; }<BR>27 1; 
        </P></BLOCKQUOTE>
      <P>&nbsp;&nbsp;&nbsp;&nbsp;第6行的require 
      Bean;语句包含了Bean.pm文件和所有相关函数,方法setCoffeeType()用于设置局域变量$class-&gt;{'Coffee'}的值。在构造函数new()中,$this指向Bean.pm返回的匿名哈希表的指针,而不是在本地创建一个,下面两个语句分别为创建不同的哈希表从而与Bean.pm构造函数创建的哈希表无关的情况和继承的情况:<BR>&nbsp;&nbsp;&nbsp;&nbsp;my 
      $this = {}; #非继承<BR>&nbsp;&nbsp;&nbsp;&nbsp;my $this = 
      $theSuperClass-&gt;new(); 
      #继承<BR>&nbsp;&nbsp;&nbsp;&nbsp;下面代码演示如何调用继承的方法:<BR></P>
      <BLOCKQUOTE>
        <P>1&nbsp; #!/usr/bin/perl<BR>2&nbsp; push (@INC,'pwd');<BR>3&nbsp; use 
        Coffee;<BR>4&nbsp; $cup = new Coffee;<BR>5&nbsp; print "\n 
        -------------------- Initial values ------------ \n";<BR>6&nbsp; print 
        "Coffee: $cup-&gt;{'Coffee'} \n";<BR>7&nbsp; print "Bean: 
        $cup-&gt;{'Bean'} \n";<BR>8&nbsp; print "\n -------------------- Change 
        Bean Type ---------- \n";<BR>9&nbsp; 
        $cup-&gt;setBeanType('Mixed');<BR>10 print "Bean Type is now 
        $cup-&gt;{'Bean'} \n";<BR>11 print "\n ------------------ Change Coffee 
        Type ---------- \n";<BR>12 $cup-&gt;setCoffeeType('Instant');<BR>13 
        print "Type of coffee: $cup-&gt;{'Coffee'} \n"; </P></BLOCKQUOTE>
      <P>&nbsp;&nbsp;&nbsp;&nbsp;该代码的结果输出如下:<BR></P>
      <BLOCKQUOTE>
        <P>-------------------- Initial values ------------<BR>Coffee: 
        Instant<BR>Bean: Colombian<BR>-------------------- Change Bean Type 
        ----------<BR>Set bean to Mixed<BR>Bean Type is now Mixed 
        <BR>------------------ Change Coffee Type ----------<BR>Set coffee type 
        to Instant<BR>Type of coffee: Instant </P></BLOCKQUOTE>
      <P>&nbsp;&nbsp;&nbsp;&nbsp;上述代码中,先输出对象创建时哈希表中索引为'Bean'和'Coffee'的值,然后调用各成员函数改变值后再输出。<BR>&nbsp;&nbsp;&nbsp;&nbsp;方法可以有多个参数,现在向Coffee.pm模块增加函数makeCup(),代码如下:<BR></P>
      <BLOCKQUOTE>
        <P>sub makeCup {<BR>&nbsp; my ($class, $cream, $sugar, $dope) = 
        @_;<BR>&nbsp; print "\n================================== \n"; 
        <BR>&nbsp; print "Making a cup \n";<BR>&nbsp; print "Add cream \n" if 
        ($cream);<BR>&nbsp; print "Add $sugar sugar cubes\n" if 
        ($sugar);<BR>&nbsp; print "Making some really addictive coffee ;-) \n" 
        if ($dope);<BR>&nbsp; print "================================== 
        \n";<BR>} </P></BLOCKQUOTE>
      <P>&nbsp;&nbsp;&nbsp;&nbsp;此函数可有三个参数,不同数目、值的参数产生不同的结果,例如:<BR></P>
      <BLOCKQUOTE>
        <P>1&nbsp; #!/usr/bin/perl<BR>2&nbsp; push (@INC,'pwd');<BR>3&nbsp; use 
        Coffee;<BR>4&nbsp; $cup = new Coffee;<BR>5&nbsp; #<BR>6&nbsp; # With no 
        parameters<BR>7&nbsp; #<BR>8&nbsp; print "\n Calling with no parameters: 
        \n";<BR>9&nbsp; $cup-&gt;makeCup;<BR>10 #<BR>11 # With one 
        parameter<BR>12 #<BR>13 print "\n Calling with one parameter: \n";<BR>14 
        $cup-&gt;makeCup('1');<BR>15 #<BR>16 # With two parameters<BR>17 #<BR>18 
        print "\n Calling with two parameters: \n";<BR>19 
        $cup-&gt;makeCup(1,'2');<BR>20 #<BR>21 # With all three parameters<BR>22 
        #<BR>23 print "\n Calling with three parameters: \n";<BR>24 
        $cup-&gt;makeCup('1',3,'1'); </P></BLOCKQUOTE>
      <P>&nbsp;&nbsp;&nbsp;&nbsp;其结果输出如下:<BR></P>
      <BLOCKQUOTE>
        <P>Calling with no 
        parameters:<BR>==================================<BR>Making a 
        cup<BR>==================================<BR>Calling with one 
        parameter:<BR>==================================<BR>Making a cup<BR>Add 
        cream<BR>==================================<BR>Calling with two 
        parameters:<BR>==================================<BR>Making a cup<BR>Add 
        cream<BR>Add 2 sugar 
        cubes<BR>==================================<BR>Calling with three 
        parameters:<BR>==================================<BR>Making a cup<BR>Add 
        cream<BR>Add 3 sugar cubes<BR>Making some really addictive coffee 
        ;-)<BR>================================== </P></BLOCKQUOTE>
      <P>&nbsp;&nbsp;&nbsp;&nbsp;在此例中,函数makeCup()的参数既可为字符串也可为整数,处理结果相同,你也可以把这两种类型的数据处理区分开。在对参数的处理中,可以设置缺省的值,也可以根据实际输入参数值的个数给予不同处理。<BR><BR><A 
      name=11>十一、子类方法的重载</A><BR>&nbsp;&nbsp;&nbsp;&nbsp;继承的好处在于可以获得基类输出的方法的功能,而有时需要对基类的方法重载以获得更具体或不同的功能。下面在Bean.pm类中加入方法printType(),代码如下:<BR></P>
      <BLOCKQUOTE>
        <P>sub printType {<BR>&nbsp; my $class = shift @_;<BR>&nbsp; print "The 
        type of Bean is $class-&gt;{'Bean'} \n";<BR>} </P></BLOCKQUOTE>
      <P>&nbsp;&nbsp;&nbsp;&nbsp;然后更新其@EXPORT数组来输出:<BR>&nbsp;&nbsp;&nbsp;&nbsp;@EXPORT 
      = qw ( setBeanType , printType 
      );<BR>&nbsp;&nbsp;&nbsp;&nbsp;现在来调用函数printType(),有三种调用方法:<BR></P>
      <BLOCKQUOTE>
        <P>$cup-&gt;Coffee::printType();<BR>$cup-&gt;printType();<BR>$cup-&gt;Bean::printType(); 
        </P></BLOCKQUOTE>
      <P>&nbsp;&nbsp;&nbsp;&nbsp;输出分别如下:<BR></P>
      <BLOCKQUOTE>
        <P>The type of Bean is Mixed<BR>The type of Bean is Mixed<BR>The type of 
        Bean is Mixed </P></BLOCKQUOTE>
      <P>&nbsp;&nbsp;&nbsp;&nbsp;为什么都一样呢?因为在子类中没有定义函数printType(),所以实际均调用了基类中的方法。如果想使子类有其自己的printType()函数,必须在Coffee.pm类中加以定义:<BR></P>
      <BLOCKQUOTE>
        <P>#<BR># This routine prints the type of 
        $class-&gt;{'Coffee'}<BR>#<BR>sub printType {<BR>&nbsp; my $class = 
        shift @_;<BR>&nbsp; print "The type of Coffee is $class-&gt;{'Coffee'} 
        \n";<BR>} </P></BLOCKQUOTE>
      <P>&nbsp;&nbsp;&nbsp;&nbsp;然后更新其@EXPORT数组:<BR>&nbsp;&nbsp;&nbsp;&nbsp;@EXPORT 
      = qw(setImports, declareMain, closeMain, 
      printType);<BR>&nbsp;&nbsp;&nbsp;&nbsp;现在输出结果变成了:<BR></P>
      <BLOCKQUOTE>
        <P>The type of Coffee is Instant<BR>The type of Coffee is Instant<BR>The 
        type of Bean is Mixed </P></BLOCKQUOTE>
      <P>&nbsp;&nbsp;&nbsp;&nbsp;现在只有当给定了Bean::时才调用基类的方法,否则直接调用子类的方法。<BR>&nbsp;&nbsp;&nbsp;&nbsp;那么如果不知道基类名该如何调用基类方法呢?方法是使用伪类保留字SUPER::。在类方法内使用语法如:$this-&gt;SUPER::function(...argument 
      list...); 
      ,它将从@ISA列表中寻找。刚才的语句用SUPER::替换Bean::可以写为$cup-&gt;SUPER::printType(); 
      ,其结果输出相同,为:<BR></P>
      <BLOCKQUOTE>
        <P>The type of Bean is Mixed</P></BLOCKQUOTE>
      <P><BR><A name=12></A><FONT 
      color=#003333>十二、Perl类和对象的一些注释</FONT><BR>&nbsp;&nbsp;&nbsp;&nbsp;OOP的最大好处就是代码重用。OOP用数据封装来隐藏一些复杂的代码,Perl的包和模块通过my函数提供数据封装功能,但是Perl并不保证子类一定不会直接访问基类的变量,这确实减少了数据封装的好处,虽然这种动作是可以做到的,但却是个很坏的编程风格。<BR>注意: 
      </P>
      <BLOCKQUOTE>
        <P>1、一定要通过方法来访问类变量。<BR>2、一定不要从模块外部直接访问类变量。</P></BLOCKQUOTE>
      <P>&nbsp;&nbsp;&nbsp;&nbsp;当编写包时,应该保证方法所需的条件已具备或通过参数传递给它。在包内部,应保证对全局变量的访问只用通过方法传递的引用来访问。对于方法要使用的静态或全局数据,应该在基类中用local()来定义,子类通过调用基类来获取。有时,子类可能需要改变这种数据,这时,基类可能就不知道怎样去寻找新的数据,因此,这时最好定义对该数据的引用,子类和基类都通过引用来改变该数据。<BR>&nbsp;&nbsp;&nbsp;&nbsp;最后,你将看到如下方式来使用对象和类:<BR>&nbsp;&nbsp;&nbsp;&nbsp;use 
      coffee::Bean;<BR>&nbsp;&nbsp;&nbsp;&nbsp;这句语句的含义是“在@INC数组所有目录的Coffee子目录来寻找Bean.pm”。如果把Bean.pm移到./Coffee目录,上面的例子将用这一use语句来工作。这样的好处是有条理地组织类的代码。再如,下面的语句:<BR>&nbsp;&nbsp;&nbsp;&nbsp;use 
      Another::Sub::Menu;<BR>&nbsp;&nbsp;&nbsp;&nbsp;意味着如下子目录树:<BR>&nbsp;&nbsp;&nbsp;&nbsp;./Another/Sub/Menu.pm 
      </P></DIV></DIV></TD></TR></TBODY></TABLE>
<DIV align=center></DIV>
<DIV align=center><BR></DIV>
<DIV align=center><SPAN class=myFont><A 
href="http://www.sun126.com/perl5/perl5-12.htm">上页</A> <A 
href="http://www.sun126.com/perl5/perl5-14.htm">下页</A> <A 
href="http://www.sun126.com/perl5/perl5index.htm">回目录</A> <A 
href="http://www.sun126.com/perl5/perl5-13.htm#a"><FONT face="Arial, 宋体">Go 
Top</FONT></A></SPAN><BR><BR></DIV>
<TABLE height=50 cellSpacing=0 cellPadding=0 width="100%" bgColor=#000000 
border=0>
  <TBODY>
  <TR>
    <TD bgColor=#cccc99 height=4>
      <DIV align=center><IMG height=4 src="" width=4></DIV></TD></TR>
  <TR>
    <TD height=50>
      <DIV align=center><FONT class=myfont size=2><SPAN class=myfont><FONT 
      color=#99cc99><A href="http://www.sun126.com/bbs/ccb/index.cgi"><FONT 
      color=#99cc99>中国CCB论坛</FONT></A>  整理 麻辣 
      2003.7.10</FONT></SPAN></FONT><FONT class=myfont color=#99cc99 
      size=2><SPAN class=myfont><FONT 
      color=#99cc66><BR></FONT></SPAN></FONT><SPAN class=myfont><FONT 
      class=myfont><SPAN class=myfont><FONT face="Arial, Helvetica, sans-serif" 
      color=#99cc99>&copy; 2000 
      http://www.sun126.com</FONT></SPAN></FONT></SPAN></DIV></TD></TR></TBODY></TABLE></BODY></HTML>

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -