亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb

首頁 > 編程 > Perl > 正文

Perl5 OOP學習筆記第1/2頁

2020-10-31 15:20:30
字體:
來源:轉載
供稿:網友
在學習了Perl的基本語法之后,學習Perl的OOP,略有心得。不知道Perl各個版本之間OOP是否有區別,但是我是學習的Perl5,所以在標題上將版本號也寫出來了。因為了解到PHP4和PHP5的OOP部分就有不小的差別,所以有此擔心。
  學習Perl的OOP,最關鍵的兩件事情就是package和bless。只要把這兩個東西搞清楚也就學會大一半了。
Perl的package
  感覺Perl的package和Java還真有點相似。Java的package是以CLASSPATH中的目錄為根,按目錄定義和搜索分級包名。Perl也類似,是以@INC數組中的目錄為根,按目錄搜索分級包名。不過有一點不同,Perl的package定義貌似不需要與目錄結構對應。具體是什么樣的規則我沒有去研究,因為按目錄結構定義package是個好習慣。
  相較于Java,Perl的package還有一點很有意思。Java的每層package對應一個目錄,而最后是一個class文件對應到類名。Perl卻簡化了,package直接就把目錄和文件名都引用了進去。比如
  Java中,name.jamesfancy.MyClass,對應的是/name/jamesfancy/MyClass.class,源代碼中則分成兩句來寫
復制代碼 代碼如下:

package name.jamesfancy;
class MyClass {....}
package name.jamesfancy;
class MyClass {....}

  Perl中,name::jamesfancy::MyClass,應對的是/name/jamesfancy/MyClass.pm,源代碼中只有一句package就說明了
復制代碼 代碼如下:

package name::jamesfancy::MyClass;
package name::jamesfancy::MyClass;

  至于package中的內容,也就是變量和子程序,至于區別,稍后再說。
bless函數
  bless是用來把一個類綁定到引用類型變量的函數。很奇怪Perl為什么要用這個單詞,不過沒關系,我們可以把它想像得形象一點:就像游戲里牧師通過祝福技能為某人加上BUFF一樣,bless把一個類綁定到某個引用類型的變量,從此這個變量就受到了祝福,擁有了這個類中的變量和子程序。
  bless的用法通常是:bless($引用變量, 類名);
  引用變量貌似可以是任何引用類型的變量,我嘗試過Scalar,Array和Hash的引用,都能成功。在bless之外,這個引用變量就可以被稱之為對象了,當然它仍然是個引用,是對象的引用。
  有一點還需要注意,雖然這個對象擁有了類的變量和子程序,但我們應該把它擁有的類的變量和子程序都看成是靜態的,換句話說,就是類的成員。在這一點上,子程序的處理會比較特殊一點,但至少類的變量,也就是包變量,是不屬于對象的。因此,所有對象的數據都保存在對象引用的原始數據中。既然大家都習慣對象數據以鍵值對的方式保存,所以通常情況下,bless的引用變量,都是Hash的引用了。
  很抽象么?舉個例子。如果對OOP的成員函數還不夠了解,那就只看下面示例中每個類的test函數中第一句以后的內容不好。
復制代碼 代碼如下:

# test.pl
package TestScalar;
sub test {
my $this = shift();
print("/nIn TestScalar::test()/n");
print("Scalar:/n ${$this}/n");
}

package TestArray;
sub test {
my $this = shift();
print("/nIn TestArray::test()/n");
print("Array:/n");
foreach my $item (@{$this}) {
print(" $item/n");
}
}

package TestHash;
sub test {
my $this = shift();
print("/nIn TestHash::test()/n");
print("Hash:/n");
while (my ($key, $value) = each %{$this}) {
printf(" %-4s = %s/n", $key, $value);
}
}

package main;

my $name = "James Fancy";
my $objScalar = /$name;
my $objArray = ['James', 'Fancy', 'Jenny'];
my $objHash = {'name' => 'James', 'age' => 30};

bless($objScalar, 'TestScalar');
bless($objArray, 'TestArray');
bless($objHash, 'TestHash');

$objScalar->test();
$objArray->test();
$objHash->test();

__END__

In TestScalar::test()
Scalar:
James Fancy

In TestArray::test()
Array:
James
Fancy
Jenny

In TestHash::test()
Hash:
name = James
age = 30

從上面的示例中可以看到,分別將3種類型的引用轉變為對象。之所以要把類寫成3個而非1個,主要是為了在Test里輸出不同類型的數據。

類和對象的成員函數

  成員函數就是在package中定義的子程序。成員函數是沒有靜態和非靜態之分的,但我寧愿大家都把它看作是靜態函數,因為雖然它即可以當作類成員函數來調用,也可以當用對象成員函數來調用,但在當作對象成員函數來調用的時候,Perl偷偷的傳入了對象引用。這也解釋了為什么通常成員函數里的第一句話往往是

復制代碼 代碼如下:

my $this = shift();

當然,這里的$this只是一個局部變量,而不是關鍵字,你也可以用別的名稱來代替它。比如很多人就喜歡用$self,或者$me等。
假如,對于一個成員函數,分別用類和對象來對它進行調用,會有什么不一樣呢?再看一個示例:
復制代碼 代碼如下:

# test.pl
package MyClass;

sub test {
my ($this, @args) = @_;
print('-' x 40, "/n");
print("/$this is [$this], Ref of /$this is [", ref($this), "]/n");
print("Args: [@args]/n");
}

package main;

$obj = {};
bless($obj, 'MyClass');

MyClass->test("MyClass->test(...)");
$obj->test("/$obj->test(...)");

__END__
----------------------------------------
$this is [MyClass], Ref of $this is []
Args: [MyClass->test(...)]
----------------------------------------
$this is [MyClass=HASH(0x178a44)], Ref of $this is [MyClass]
Args: [$obj->test(...)]

從結果可以看出來,不管哪種方法調用,第一個參數都是Perl偷偷傳遞進去的。如果是類調用,則第一個參數是該類。如果是對象調用,第一個參數是該對象。因此,只需要將ref($this)的結果和類名進行比較就清楚是哪種調用了。所以,一個容錯性較好的成員函數,一開始要判斷傳入的第一個參數,比如
復制代碼 代碼如下:

sub foo {
my $this = shift();
return unless ($this ne 'MyClass');
# 其它語句
}

這里還有一個疑問:既然package中定義的子程序都是成員函數,那不是類的package和是類的package有啥區別?它們在結構上沒有一點區別,唯一的區別在處理中。在調用子程序的時候,Perl不會硬塞一個類或者對象在參數列表的最前面,但調用成員函數的時候會,所以區別是根據你的調用方式來區分的。

  調用對象成員還好說,$obj->foo()就好,但是調用類成員的時候,怎么知道是調用的類成員還是包中的子程序呢?那就要看是通過“->”還是“::”來調用的了。下面的例子可以幫助理解:
復制代碼 代碼如下:

# test.pl
package MyClass;
use Data::Dumper;
sub test {
print('-' x 40, "/n");
print(Dumper(@_));
}

package main;

MyClass->test("MyClass->test(...)");
MyClass::test("MyClass::test(...)");

__END__
----------------------------------------
$VAR1 = 'MyClass';
$VAR2 = 'MyClass->test(...)';
----------------------------------------
$VAR1 = 'MyClass::test(...)';

很明顯,通過“::”調用的子程序沒有被Perl塞入一個引用類的參數。

構造函數
  Perl的OOP沒有指定專門的構造函數,所以你可以把任何一個子程序當作構造函數,當然,重要的是其中的內容。既然腳本通常不是寫給自己一個人看的,所以還是按照大家的習慣,把構造函數取名為new吧。按照多數OOP語言的習慣,new函數通常返回一個對象或其引用、指針。所以在Perl中,這個new函數要返回一個對象引用,理所當然地,把bless動作包含在new函數中是個好習慣。那么一個簡單的new函數看起來就像這樣:
復制代碼 代碼如下:

sub new {
my $this = {};
bless($this);
}

這個new函數中產生了一個Hash引用,bless它,并返回它。如果你疑惑為什么這里沒有看到return語句,那么建議你去看看關于子程序中返回值的資料,順便查一下bless函數的說明。來看看完整的程序了解一下是怎么使用new函數的。
12下一頁閱讀全文
發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
91精品久久久久久久久| 97婷婷涩涩精品一区| 成人精品久久av网站| 亚洲国产欧美一区二区丝袜黑人| 国产精品a久久久久久| 高清一区二区三区四区五区| 国产精品中文字幕久久久| 久久综合伊人77777尤物| 久久777国产线看观看精品| 亚洲国产精品久久久久秋霞蜜臀| 成人福利视频网| 国产日韩在线免费| 国产精品偷伦免费视频观看的| 亚洲国产欧美一区二区三区同亚洲| 国产成人综合一区二区三区| 欧美极品少妇xxxxx| 欧美日韩在线看| 色播久久人人爽人人爽人人片视av| 91欧美激情另类亚洲| 精品亚洲一区二区三区在线观看| 国产精品高清在线观看| 97视频国产在线| 久久久99久久精品女同性| 日韩av在线网站| 久久偷看各类女兵18女厕嘘嘘| 中文字幕在线精品| 狠狠躁夜夜躁人人爽天天天天97| 亚洲毛片在线观看| 国产精品欧美日韩久久| 亚洲国产日韩欧美在线动漫| 九九热这里只有在线精品视| 国产一区二区三区在线免费观看| 久久久久久国产精品| 久久国产加勒比精品无码| 欧美性开放视频| 欧美日韩中文字幕日韩欧美| 成人网址在线观看| 中文字幕视频一区二区在线有码| 精品国内自产拍在线观看| 精品久久久国产| 45www国产精品网站| 在线电影欧美日韩一区二区私密| 日韩精品中文字幕在线播放| 欧美国产日韩一区二区| 成人免费观看49www在线观看| 欧美激情精品久久久久久| 欧美黄色免费网站| 欧美成人免费在线视频| 亚洲免费一在线| 亚洲美女自拍视频| 一区二区三区视频免费在线观看| 久久久999国产精品| 日韩精品福利在线| 久久精品中文字幕电影| 国产97在线视频| 日韩a**中文字幕| 亚洲国产精品va在线| 国产精品私拍pans大尺度在线| 66m—66摸成人免费视频| 欧美性高跟鞋xxxxhd| 毛片精品免费在线观看| 国产精品99一区| 欧美精品免费在线观看| 久久99久国产精品黄毛片入口| 成人黄色免费网站在线观看| 亚洲第一精品自拍| 日韩av在线高清| 久久精品91久久久久久再现| 欧美午夜www高清视频| 日韩精品有码在线观看| 国产91对白在线播放| 庆余年2免费日韩剧观看大牛| 亚洲国产高清自拍| 亚洲成av人片在线观看香蕉| 久久的精品视频| 中文字幕欧美视频在线| 日韩午夜在线视频| 日韩精品高清在线| 欧美性极品少妇精品网站| 久久精品99久久香蕉国产色戒| 亚洲一区二区三区视频播放| 国产精品久久一区主播| 激情av一区二区| 亚洲a中文字幕| 欧美黑人巨大精品一区二区| 国产成人综合亚洲| 欧美激情亚洲综合一区| 国内自拍欧美激情| 亚洲成人久久久久| 国产精品免费一区二区三区都可以| 亚洲国产欧美一区二区三区久久| 欧美日本精品在线| 91福利视频在线观看| 亚洲视频在线视频| 琪琪亚洲精品午夜在线| 国产精品美女在线观看| 色狠狠av一区二区三区香蕉蜜桃| 亚洲精品国产综合久久| 欧美专区在线播放| 亚洲一区美女视频在线观看免费| 国产精品∨欧美精品v日韩精品| 成人xxxx视频| 国内精品在线一区| 中文字幕亚洲一区在线观看| 国产人妖伪娘一区91| 青青草国产精品一区二区| 久久精品99久久久久久久久| 成人美女av在线直播| 日韩有码在线视频| 亚洲欧美激情四射在线日| 91精品成人久久| 国产亚洲精品美女| 国产亚洲精品美女久久久久| 91精品国产自产91精品| 91精品综合久久久久久五月天| 91高清视频在线免费观看| 亚洲国产日韩欧美综合久久| 亚洲黄页视频免费观看| 亚洲人高潮女人毛茸茸| 欧美激情视频网站| 午夜精品福利电影| 在线播放国产一区中文字幕剧情欧美| 一区二区三区精品99久久| 久久久91精品国产| 麻豆国产va免费精品高清在线| 中文字幕亚洲国产| 亚洲品质视频自拍网| 精品久久久久久中文字幕大豆网| 国产精品精品一区二区三区午夜版| 欧美日韩国产丝袜另类| 国产精品久久久久久久久久ktv| 欧美日韩亚洲高清| 久久久久久久久久av| 国产情人节一区| 欧美性极品xxxx做受| 亚洲影院高清在线| 国产精品91免费在线| 在线免费观看羞羞视频一区二区| 国产成人jvid在线播放| 欧美激情综合亚洲一二区| 亚洲成人性视频| 久久精品影视伊人网| 国产精品自在线| 久久影视电视剧免费网站清宫辞电视| 国产成人综合精品在线| 亚洲色图在线观看| 国产一区二区三区中文| 日韩高清电影免费观看完整| 日韩中文有码在线视频| 亚洲天堂第一页| 久久久爽爽爽美女图片| 日韩av影视综合网| 国产美女久久精品| 欧美—级高清免费播放| 懂色av中文一区二区三区天美| 国产mv免费观看入口亚洲| 久久久久久久一区二区| 欧美国产高跟鞋裸体秀xxxhd| 欧美性xxxxx极品| 久久久精品国产| 亚洲第一综合天堂另类专| 亚洲欧洲一区二区三区久久| 欧美激情国产高清| 国产综合色香蕉精品|