?? perl 語言-perl 中文教程(第十三章).htm
字號(hào):
<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> 注意:如果用->操作符調(diào)用方法(也叫間接調(diào)用),參數(shù)必須用括號(hào)括起來,如:$cup->setImports(
'java.io.InputStream', 'java.net.*');而雙冒號(hào)調(diào)用如:Cocoa::setImports($cup,
'java.io.InputStream', 'java.net.*');也可去掉括號(hào)寫成:Cocoa::setImports $cup,
'java.io.InputStream', 'java.net.*' ;<BR><BR><A
name=8>八、重載</A><BR> 有時(shí)需要指定使用哪個(gè)類的方法,如兩個(gè)不同的類有同名方法的時(shí)候。假設(shè)類Espresso和Qava都定義了方法grind,可以用::操作符指定使用Qava的方法:<BR> $mess
=
Qava::grind("whole","lotta","bags");<BR> Qava::grind($mess,
"whole","lotta","bags");<BR> 可以根據(jù)程序的運(yùn)行情況來選擇使用哪個(gè)類的方法,這可以通過使用符號(hào)引用去調(diào)用來實(shí)現(xiàn):<BR> $method
= $local ? "Qava::" :
"Espresso::";<BR> $cup->{$method}grind(@args);<BR><BR><A
name=9>九、析構(gòu)函數(shù)</A><BR> Perl跟蹤對(duì)象的鏈接數(shù)目,當(dāng)某對(duì)象的最后一個(gè)應(yīng)用釋放到內(nèi)存池時(shí),該對(duì)象就自動(dòng)銷毀。對(duì)象的析構(gòu)發(fā)生在代碼停止后,腳本將要結(jié)束時(shí)。對(duì)于全局變量而言,析構(gòu)發(fā)生在最后一行代碼運(yùn)行之后。<BR> 如果你想在對(duì)象被釋放之前獲取控制權(quán),可以定義DESTROY()方法。DESTROY()在對(duì)象將釋放前被調(diào)用,使你可以做一些清理工作。DESTROY()函數(shù)不自動(dòng)調(diào)用其它DESTROY()函數(shù),Perl不做內(nèi)置的析構(gòu)工作。如果構(gòu)造函數(shù)從基類多次bless,DESTROY()可能需要調(diào)用其它類的DESTROY()函數(shù)。當(dāng)一個(gè)對(duì)象被釋放時(shí),其內(nèi)含的所有對(duì)象引用自動(dòng)釋放、銷毀。<BR> 一般來說,不需要定義DESTROY()函數(shù),如果需要,其形式如下:<BR></P>
<BLOCKQUOTE>
<P>sub DESTROY {<BR>#<BR># Add code here.<BR>#<BR>} </P></BLOCKQUOTE>
<P> 因?yàn)槎喾N目的,Perl使用了簡(jiǎn)單的、基于引用的垃圾回收系統(tǒng)。任何對(duì)象的引用數(shù)目必須大于零,否則該對(duì)象的內(nèi)存就被釋放。當(dāng)程序退出時(shí),Perl的一個(gè)徹底的查找并銷毀函數(shù)進(jìn)行垃圾回收,進(jìn)程中的一切被簡(jiǎn)單地刪除。在UNIX類的系統(tǒng)中,這像是多余的,但在內(nèi)嵌式系統(tǒng)或多線程環(huán)境中這確實(shí)很必要。<BR><A
name=10>十、繼承</A><BR> 類方法通過@ISA數(shù)組繼承,變量的繼承必須明確設(shè)定。下例創(chuàng)建兩個(gè)類Bean.pm和Coffee.pm,其中Coffee.pm繼承Bean.pm的一些功能。此例演示如何從基類(或稱超類)繼承實(shí)例變量,其方法為調(diào)用基類的構(gòu)造函數(shù)并把自己的實(shí)例變量加到新對(duì)象中。<BR> Bean.pm代碼如下:<BR></P>
<BLOCKQUOTE>
<P>package Bean;<BR>require Exporter;<BR>@ISA = qw(Exporter);<BR>@EXPORT
= qw(setBeanType);<BR><BR>sub new {<BR> my $type =
shift;<BR> my $this = {};<BR> $this->{'Bean'} =
'Colombian';<BR> bless $this, $type;<BR> return
$this;<BR>}<BR><BR>#<BR># This subroutine sets the class name<BR>sub
setBeanType{<BR> my ($class, $name) = @_;<BR>
$class->{'Bean'} = $name;<BR> print "Set bean to $name
\n";<BR>}<BR>1; </P></BLOCKQUOTE>
<P> 此類中,用$this變量設(shè)置一個(gè)匿名哈希表,將'Bean'類型設(shè)為'Colombian'。方法setBeanType()用于改變'Bean'類型,它使用$class引用獲得對(duì)對(duì)象哈希表的訪問。<BR> Coffee.pm代碼如下:<BR></P>
<BLOCKQUOTE>
<P>1 #<BR>2 # The Coffee.pm file to illustrate
inheritance.<BR>3 #<BR>4 package Coffee;<BR>5 require
Exporter;<BR>6 require Bean;<BR>7 @ISA = qw(Exporter,
Bean);<BR>8 @EXPORT = qw(setImports, declareMain,
closeMain);<BR>9 #<BR>10 # set item<BR>11 #<BR>12 sub
setCoffeeType{<BR>13 my ($class,$name) = @_;<BR>14
$class->{'Coffee'} = $name;<BR>15 print "Set coffee type to
$name \n";<BR>16 }<BR>17 #<BR>18 # constructor<BR>19 #<BR>20 sub
new {<BR>21 my $type = shift;<BR>22 my $this =
Bean->new(); ##### <- LOOK HERE!!! ####<BR>23
$this->{'Coffee'} = 'Instant'; # unless told otherwise<BR>24
bless $this, $type;<BR>25 return $this;<BR>26 }<BR>27 1;
</P></BLOCKQUOTE>
<P> 第6行的require
Bean;語句包含了Bean.pm文件和所有相關(guān)函數(shù),方法setCoffeeType()用于設(shè)置局域變量$class->{'Coffee'}的值。在構(gòu)造函數(shù)new()中,$this指向Bean.pm返回的匿名哈希表的指針,而不是在本地創(chuàng)建一個(gè),下面兩個(gè)語句分別為創(chuàng)建不同的哈希表從而與Bean.pm構(gòu)造函數(shù)創(chuàng)建的哈希表無關(guān)的情況和繼承的情況:<BR> my
$this = {}; #非繼承<BR> my $this =
$theSuperClass->new();
#繼承<BR> 下面代碼演示如何調(diào)用繼承的方法:<BR></P>
<BLOCKQUOTE>
<P>1 #!/usr/bin/perl<BR>2 push (@INC,'pwd');<BR>3 use
Coffee;<BR>4 $cup = new Coffee;<BR>5 print "\n
-------------------- Initial values ------------ \n";<BR>6 print
"Coffee: $cup->{'Coffee'} \n";<BR>7 print "Bean:
$cup->{'Bean'} \n";<BR>8 print "\n -------------------- Change
Bean Type ---------- \n";<BR>9
$cup->setBeanType('Mixed');<BR>10 print "Bean Type is now
$cup->{'Bean'} \n";<BR>11 print "\n ------------------ Change Coffee
Type ---------- \n";<BR>12 $cup->setCoffeeType('Instant');<BR>13
print "Type of coffee: $cup->{'Coffee'} \n"; </P></BLOCKQUOTE>
<P> 該代碼的結(jié)果輸出如下:<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> 上述代碼中,先輸出對(duì)象創(chuàng)建時(shí)哈希表中索引為'Bean'和'Coffee'的值,然后調(diào)用各成員函數(shù)改變值后再輸出。<BR> 方法可以有多個(gè)參數(shù),現(xiàn)在向Coffee.pm模塊增加函數(shù)makeCup(),代碼如下:<BR></P>
<BLOCKQUOTE>
<P>sub makeCup {<BR> my ($class, $cream, $sugar, $dope) =
@_;<BR> print "\n================================== \n";
<BR> print "Making a cup \n";<BR> print "Add cream \n" if
($cream);<BR> print "Add $sugar sugar cubes\n" if
($sugar);<BR> print "Making some really addictive coffee ;-) \n"
if ($dope);<BR> print "==================================
\n";<BR>} </P></BLOCKQUOTE>
<P> 此函數(shù)可有三個(gè)參數(shù),不同數(shù)目、值的參數(shù)產(chǎn)生不同的結(jié)果,例如:<BR></P>
<BLOCKQUOTE>
<P>1 #!/usr/bin/perl<BR>2 push (@INC,'pwd');<BR>3 use
Coffee;<BR>4 $cup = new Coffee;<BR>5 #<BR>6 # With no
parameters<BR>7 #<BR>8 print "\n Calling with no parameters:
\n";<BR>9 $cup->makeCup;<BR>10 #<BR>11 # With one
parameter<BR>12 #<BR>13 print "\n Calling with one parameter: \n";<BR>14
$cup->makeCup('1');<BR>15 #<BR>16 # With two parameters<BR>17 #<BR>18
print "\n Calling with two parameters: \n";<BR>19
$cup->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->makeCup('1',3,'1'); </P></BLOCKQUOTE>
<P> 其結(jié)果輸出如下:<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> 在此例中,函數(shù)makeCup()的參數(shù)既可為字符串也可為整數(shù),處理結(jié)果相同,你也可以把這兩種類型的數(shù)據(jù)處理區(qū)分開。在對(duì)參數(shù)的處理中,可以設(shè)置缺省的值,也可以根據(jù)實(shí)際輸入?yún)?shù)值的個(gè)數(shù)給予不同處理。<BR><BR><A
name=11>十一、子類方法的重載</A><BR> 繼承的好處在于可以獲得基類輸出的方法的功能,而有時(shí)需要對(duì)基類的方法重載以獲得更具體或不同的功能。下面在Bean.pm類中加入方法printType(),代碼如下:<BR></P>
<BLOCKQUOTE>
<P>sub printType {<BR> my $class = shift @_;<BR> print "The
type of Bean is $class->{'Bean'} \n";<BR>} </P></BLOCKQUOTE>
<P> 然后更新其@EXPORT數(shù)組來輸出:<BR> @EXPORT
= qw ( setBeanType , printType
);<BR> 現(xiàn)在來調(diào)用函數(shù)printType(),有三種調(diào)用方法:<BR></P>
<BLOCKQUOTE>
<P>$cup->Coffee::printType();<BR>$cup->printType();<BR>$cup->Bean::printType();
</P></BLOCKQUOTE>
<P> 輸出分別如下:<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> 為什么都一樣呢?因?yàn)樵谧宇愔袥]有定義函數(shù)printType(),所以實(shí)際均調(diào)用了基類中的方法。如果想使子類有其自己的printType()函數(shù),必須在Coffee.pm類中加以定義:<BR></P>
<BLOCKQUOTE>
<P>#<BR># This routine prints the type of
$class->{'Coffee'}<BR>#<BR>sub printType {<BR> my $class =
shift @_;<BR> print "The type of Coffee is $class->{'Coffee'}
\n";<BR>} </P></BLOCKQUOTE>
<P> 然后更新其@EXPORT數(shù)組:<BR> @EXPORT
= qw(setImports, declareMain, closeMain,
printType);<BR> 現(xiàn)在輸出結(jié)果變成了:<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> 現(xiàn)在只有當(dāng)給定了Bean::時(shí)才調(diào)用基類的方法,否則直接調(diào)用子類的方法。<BR> 那么如果不知道基類名該如何調(diào)用基類方法呢?方法是使用偽類保留字SUPER::。在類方法內(nèi)使用語法如:$this->SUPER::function(...argument
list...);
,它將從@ISA列表中尋找。剛才的語句用SUPER::替換Bean::可以寫為$cup->SUPER::printType();
,其結(jié)果輸出相同,為:<BR></P>
<BLOCKQUOTE>
<P>The type of Bean is Mixed</P></BLOCKQUOTE>
<P><BR><A name=12></A><FONT
color=#003333>十二、Perl類和對(duì)象的一些注釋</FONT><BR> OOP的最大好處就是代碼重用。OOP用數(shù)據(jù)封裝來隱藏一些復(fù)雜的代碼,Perl的包和模塊通過my函數(shù)提供數(shù)據(jù)封裝功能,但是Perl并不保證子類一定不會(huì)直接訪問基類的變量,這確實(shí)減少了數(shù)據(jù)封裝的好處,雖然這種動(dòng)作是可以做到的,但卻是個(gè)很壞的編程風(fēng)格。<BR>注意:
</P>
<BLOCKQUOTE>
<P>1、一定要通過方法來訪問類變量。<BR>2、一定不要從模塊外部直接訪問類變量。</P></BLOCKQUOTE>
<P> 當(dāng)編寫包時(shí),應(yīng)該保證方法所需的條件已具備或通過參數(shù)傳遞給它。在包內(nèi)部,應(yīng)保證對(duì)全局變量的訪問只用通過方法傳遞的引用來訪問。對(duì)于方法要使用的靜態(tài)或全局?jǐn)?shù)據(jù),應(yīng)該在基類中用local()來定義,子類通過調(diào)用基類來獲取。有時(shí),子類可能需要改變這種數(shù)據(jù),這時(shí),基類可能就不知道怎樣去尋找新的數(shù)據(jù),因此,這時(shí)最好定義對(duì)該數(shù)據(jù)的引用,子類和基類都通過引用來改變?cè)摂?shù)據(jù)。<BR> 最后,你將看到如下方式來使用對(duì)象和類:<BR> use
coffee::Bean;<BR> 這句語句的含義是“在@INC數(shù)組所有目錄的Coffee子目錄來尋找Bean.pm”。如果把Bean.pm移到./Coffee目錄,上面的例子將用這一use語句來工作。這樣的好處是有條理地組織類的代碼。再如,下面的語句:<BR> use
Another::Sub::Menu;<BR> 意味著如下子目錄樹:<BR> ./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>中國(guó)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>© 2000
http://www.sun126.com</FONT></SPAN></FONT></SPAN></DIV></TD></TR></TBODY></TABLE></BODY></HTML>
?? 快捷鍵說明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號(hào)
Ctrl + =
減小字號(hào)
Ctrl + -