??????? 之前一直在學習c++,c++給我的感覺就像正規(guī)軍編程的絕對主力部隊撬呢,嚴謹伦吠、高效一絲不茍,其語法雖然復(fù)雜但是都有章可循有法魂拦。因為喜歡linux的原因毛仪,學習了perl語言,perl語言給我的感覺就像雇傭軍芯勘,從來不循規(guī)蹈矩箱靴,也從來不是主力,但是在解決特定問題上它就像一把屠龍刀荷愕,直切要害毫不留情衡怀。學習c++時很多問題比如類、對象等很抽象安疗,可能你現(xiàn)在看懂了過幾天就忘了抛杨,學習perl有助于理解c++面向?qū)ο缶幊痰暮芏鄦栴},因為用perl編程就像在和計算機說話其語法很容易理解荐类,c++編程呢則像在簽合同蝶桶,大段大段的條條框框讓人云里霧里。現(xiàn)在我們就從perl入手學習下面向?qū)ο缶幊獭?/p>
1掉冶、什么是對象真竖?
????? 有人要問了什么是對象脐雪,(當然不是你女朋友或老婆!;止病)战秋,相信各位在初學編程(當然我也是初學)時總是以為程序就像流水線從開始到結(jié)束然后輸出成品。這樣固然很不錯讨韭,但是其靈活性大大降低脂信。而面向?qū)ο缶幊虅t是你創(chuàng)造一個對象,這個對象有自己的數(shù)據(jù)(這些數(shù)據(jù)定義這個對象是什么)透硝,然后你給他創(chuàng)造各種各樣的接口(接口則定于這個對象會干什么狰闪,有點像人的手腳的感覺)。構(gòu)造了12個對象濒生,ok你就可以用這12個對象組成球隊去比賽埋泵,不知道這樣的解釋能不能理解。現(xiàn)在我們就構(gòu)建一個person類來逐步拆解罪治。
2丽声、perl中的數(shù)據(jù)(見以下代碼)
??????? #!/usr/bin/perl? ?
??????? use v5.22.3;
??????? package Person;
??????? my %field=("Person::name"=>"unknown","Person::sex"=>"unknown","Person::age"=>"unknown",
"Person::relationship_with_u"="unknown");
在這里強調(diào)下定義變量名稱時采用包名::變量名的方式,規(guī)范點的寫法對你有好處觉义。
my %field散列就是Person這個類中存儲這個類屬性的容器雁社,通過定義這些屬性我們可以知道這個類對象是個什么樣的人,在上述代碼中如果構(gòu)造函數(shù)不提供參數(shù)則這個人姓名:未知晒骇,性別:未知霉撵,年齡:未知,和你的關(guān)系:未知(唔真是一個神秘的對象)洪囤,下面我們就來構(gòu)造我們的對象徒坡。
3、構(gòu)造函數(shù)
???? 構(gòu)造函數(shù)的作用就是真正把這個類變成你的對象箍鼓,這里我們講兩個方法第一個普通方法,第二個采用閉包確保實現(xiàn)私有對象呵曹。
????? (1)款咖、普通構(gòu)造函數(shù):
sub new{
????? my $class=shift;#構(gòu)造函數(shù)有個隱含的參數(shù)在@_數(shù)組第一個位置,就是調(diào)用該類方法的類名稱奄喂。在這里我們先將該名稱存儲到$class變量中铐殃。以后有用。
????? my $class=ref($class)||$class; #這一句是可選項實現(xiàn)以構(gòu)造好的對象為模板構(gòu)造新的對象跨新。
????? my $self={%field,@_};? # 如果參數(shù)為空則$self采用默認的屬性富腊,你的對象一切未知,如果有參數(shù)則參數(shù)會存儲在@_數(shù)組中域帐,并覆蓋%field的相關(guān)鍵/值對赘被,你看這個perl的語法多么精煉是整。
????? return bless $self,$class;? #最重要的將$self這個散列祝福到Person,有點像上帝給Person這個軀體注入(bless)靈魂的感覺民假。
}
這樣我們就可以調(diào)用該構(gòu)造函數(shù)構(gòu)造你的對象了浮入。
my $wife=Person::->new("Person::name"=>"YSQ","Person::sex"=>"female","Person::age"=>"25",)
"Person::relationship_with_u"="wife");誒嘿嘿,現(xiàn)在你就有了一個叫YSQ羊异,性別女事秀,年齡25歲的老婆了,你的對象來了野舶,趕緊面向她編程吧易迹。
????? (2)使用閉包實現(xiàn)私有對象
既然你已經(jīng)構(gòu)造一個老婆,咳咳那你肯定希望她是私有的平道,普通的構(gòu)造函數(shù)構(gòu)造的對象可以任意修改你的對象屬性睹欲,如果有bad boy把你老婆的Person::sex修改為man,我想你可能要注意你的ju hua了巢掺。廢話不多說用閉包的方法保護你的老婆吧句伶。
?sub new1{
???????? my $class=shift;
???????? $class=ref($class)||$class;
???????? my $data={%field,@_};
???????? my $self=sub{
???????????????????? my $key=shift;
???????????????????? ##這里可以插入相應(yīng)的訪問檢查
????????????????????? if (@_) {$data->{$key}=shift;}
????????????????????? return $data->{$key};
????????????????????? };
????????? bless ($self,$class);
?????????? return $self;
}
在這里我們的構(gòu)造函數(shù)不再是返回一個匿名的散列了,而是返回一個閉包陆淀。
現(xiàn)在通過例子來講解考余,同樣通過my $wife=Person::->new1("Person::name"=>"YSQ","Person::sex"=>"female","Person::age"=>"25",
"Person::relationship_with_u"="wife");生成你的對象,但注意這里的$wife是一個閉包引用哦,什么意思呢轧苫,用普通構(gòu)造函數(shù)構(gòu)造的$wife可以用$wife{name}來直接讀取并修改您$wife的屬性楚堤,現(xiàn)在不行了$wife是一個閉包對象!是一個函數(shù)含懊,它只能通過$wife->("name","YSQ2")的形式改變身冬。 也就是說只有調(diào)用閉包函數(shù)才能讀取我們$wife的內(nèi)部屬性。也就是相應(yīng)的name接口方法岔乔。這里可能不太好理解我們把name具體化為一個方法酥筝。
for my $method(qw(name sex age relationship))
{
no strict "refs";
*$method=sub{
my $self=shift;
return $self->($method,@_);
};
}
我們把name做成一個閉包函數(shù),這時name是一個接口雏门,我們只能通過這個接口訪問$wife的名字嘿歌。$wife->name("YSQ2")等同于$wife->("name","YSQ2")。這一段比較難看懂茁影,要先惡補下閉包的知識宙帝。