浅谈Perl的类、包、模块与面对对象编程
生活随笔
收集整理的這篇文章主要介紹了
浅谈Perl的类、包、模块与面对对象编程
小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.
http://blog.chinaunix.net/uid-27464093-id-3308003.html
Perl面向?qū)ο驪erl面向?qū)ο髮W(xué)習(xí)例子實例代碼教程 - 在我們了解perl的面向?qū)ο蟮母拍铋_始之前,讓我們了解引用和匿名數(shù)組和哈希表。 在我們了解perl的面向?qū)ο蟮母拍铋_始之前,讓我們了解引用和匿名數(shù)組和哈希表。引用 引用是完全像名稱所暗示的一樣,給另一個對象的引用或指針。有兩種類型的引用:符號和硬引用。 一個符號參考,使您能夠引用一個變量的名稱,使用另一個變量值。 例如,如果變量$foo的包含字符串“bar”,符號引用$foo的關(guān)聯(lián)變量$bar。一個硬引用是指在數(shù)據(jù)結(jié)構(gòu)中包含的實際數(shù)據(jù)。創(chuàng)建硬引用 一元反斜線運(yùn)算符用于創(chuàng)建一個命名的變量或子程序,例如:$foo = 'Bill'; $fooref = \$foo; 現(xiàn)在$fooref變量一個硬引用$foo的變量。你可以做同樣的與其他變量:$array = \@ARGV; $hash = \%ENV; $glob = \*STDOUT; 要創(chuàng)建一個子程序:sub foo { print "foo" }; $foosub = \&foo; 匿名數(shù)組 當(dāng)你直接創(chuàng)建一個引用到一個數(shù)組 - 也就是說,沒有形成中間指定數(shù)組 - 您正在創(chuàng)建一個匿名數(shù)組。創(chuàng)建一個匿名數(shù)組是很容易的:$array = [ 'Bill', 'Ben, 'Mary' ]; 這一行分配一個數(shù)組,由封閉的方括號中,而不是正常的括號表示,標(biāo)量$array。賦值的右側(cè)上的值,使該陣列和左側(cè)包含此陣列的參考。您可以創(chuàng)建更復(fù)雜的結(jié)構(gòu),通過嵌套數(shù)組:@arrayarray = ( 1, 2, [1, 2, 3]); @array數(shù)組包含三個元素,一個匿名的三個元素的數(shù)組的第三個元素是一個引用。匿名散列 匿名哈希,你也很容易創(chuàng)建需要使用大括號方括號:$hash = { 'Man' => 'Bill', 'Woman' => 'Mary, 'Dog' => 'Ben' }; 解除引用 解引用一個參考的最直接的方法是在前面加上相應(yīng)的數(shù)據(jù)類型的字符(標(biāo)量使用$,陣列使用@,哈希使用%,子程序用&)是你期待在前面的標(biāo)量量變量包含的引用。 $array = \@ARGV; # Create reference to array $hash = \%ENV; # Create reference to hash $glob = \*STDOUT; # Create reference to typeglob $foosub = \&foo; # Create reference to subroutine #by www.yiibai.com push (@$array, "From humans"); $$array[0] = 'Hello' $$hash{'Hello'} = 'World'; &$foosub; print $glob "Hello World!\n"; 對象基礎(chǔ) 主要有三種,解釋的Perl如何處理對象的角度來看。 該使用條款是對象,類和方法。在Perl中,對象僅僅是一個參考的數(shù)據(jù)類型,它知道它屬于什么類。對象存儲在一個標(biāo)量變量作為參考。因為一個標(biāo)量只包含一個對象的引用,同樣的標(biāo)量可以容納不同的對象,不同的類中。在Perl中類是一個包,其中包含需要相應(yīng)的方法來創(chuàng)建和操作對象。在Perl中一個子程序,程序包定義的方法。該方法的第一個參數(shù)是一個對象引用或包名稱,取決于該方法是否影響當(dāng)前對象或類。Perl提供了bless()函數(shù),用于返回一個引用,并成為一個對象。 定義一個類 定義一個類很簡單。在Perl中類是對應(yīng)于一個包。要創(chuàng)建一個類,我們先建立一個包。包是一個獨(dú)立的單元,用戶定義的變量和子程序,它可以被重新使用一遍又一遍。他們提供了一個單獨(dú)的命名空間內(nèi)保持一個Perl程序,子程序和變量以免與其他包中的沖突。要聲明一個類名為Person,我們做:package Person; 包定義的范圍延伸到該文件的末尾,或直到遇到另一個package關(guān)鍵字。 創(chuàng)建和使用對象 要創(chuàng)建一個類的實例(對象),我們需要一個對象的構(gòu)造函數(shù)。此構(gòu)造函數(shù)是一個在包中定義的方法。大多數(shù)程序員來命名這種新對象的構(gòu)造方法,但在Perl中,可以使用任何名稱。在Perl中的對象,我們可以使用任何類型的Perl變量。大多數(shù)Perl程序員選擇使用數(shù)組或哈希表的引用。讓我們來創(chuàng)建我們的構(gòu)造函數(shù)使用一個Perl的哈希參考我們的Person類;當(dāng)創(chuàng)建一個對象,你需要提供一個構(gòu)造函數(shù)。這是一個子程序,它返回一個對象引用在一個包內(nèi)。blessing包的類創(chuàng)建的對象引用。例如:package Person; sub new { my $class = shift; my $self = { _firstName => shift, _lastName => shift, _ssn => shift, }; # Print all the values just for clarification. #by www.yiibai.com print "First Name is $self->{_firstName}\n"; print "Last Name is $self->{_lastName}\n"; print "SSN is $self->{_ssn}\n"; bless $self, $class; return $self; } 每類方法通過類名作為第一個參數(shù)。 因此,在上面的例子中的類名是“Person”。你可以試試這個打印$class的值。下一步將剩下的參數(shù)傳遞的方法。$object = new Person( "Mohammad", "Saleem", 23234345); 如果不希望任何類變量分配任何值,可以使用簡單的哈希在構(gòu)造函數(shù)。例如 package Person; sub new { my $class = shift; my $self = {}; bless $self, $class; return $self; } 定義方法 其它面向?qū)ο笳Z言的概念,如:數(shù)據(jù)的安全性,以防止程序員等提供直接改變一個對象的數(shù)據(jù)訪問方法來修改對象數(shù)據(jù)。 Perl沒有私有變量,但我們?nèi)匀豢梢允褂幂o助函數(shù)的方法,讓程序員不要亂用對象內(nèi)部結(jié)構(gòu)的概念。讓我們來定義一個輔助方法來獲得人的名字:sub getFirstName { return $self->{_firstName}; } 另一種輔助函數(shù)來設(shè)置人的名字:sub setFirstName { my ( $self, $firstName ) = @_; $self->{_firstName} = $firstName if defined($firstName); return $self->{_firstName}; } 讓我們看看到完整的例子:保持Person 包和輔助功能Person.pm文件。 #!/usr/bin/perl package Person; sub new { my $class = shift; my $self = { _firstName => shift, _lastName => shift, _ssn => shift, }; # Print all the values just for clarification. print "First Name is $self->{_firstName}\n"; print "Last Name is $self->{_lastName}\n"; print "SSN is $self->{_ssn}\n"; bless $self, $class; return $self; } sub setFirstName { my ( $self, $firstName ) = @_; $self->{_firstName} = $firstName if defined($firstName); return $self->{_firstName}; } #by www.yiibai.com sub getFirstName { my( $self ) = @_; return $self->{_firstName}; } 1; 現(xiàn)在,在mail.pl文件創(chuàng)建Person對象如下#!/usr/bin/perl use Person; $object = new Person( "Mohammad", "Saleem", 23234345); # Get first name which is set using constructor. $firstName = $object->getFirstName(); print "Before Setting First Name is : $firstName\n"; # Now Set first name using helper function. $object->setFirstName( "Mohd." ); # Now get first name set by helper function. $firstName = $object->getFirstName(); print "Before Setting First Name is : $firstName\n"; This will produce following result First Name is Mohammad Last Name is Saleem SSN is 23234345 Before Setting First Name is : Mohammad Before Setting First Name is : Mohd. 繼承 面向?qū)ο缶幊?#xff0c;有時涉及繼承。繼承僅僅意味著允許一個類被稱為“子類“從另一個類繼承方法和屬性,調(diào)用父類, 這樣你就不會一遍又一遍寫相同的代碼。例如,我們可以有一個Employee類繼承自Person。 這被稱為“是一個”的關(guān)系,因為雇員是一個人。Perl有一個特殊的變量@ISA來鋪助,@ISA 管理(方法)繼承。 以下是使用繼承說明Perl搜索指定對象的指定對象的類。Perl搜索類中定義的對象類的@ISA陣列。如果沒有在步驟1和2找到方法,那么如果找到一個在@ ISA樹,Perl使用AUTOLOAD子程序, 如果仍然無法找到匹配的方法,那么Perl搜索的方法在通用類(包),標(biāo)準(zhǔn)的Perl庫的一部分。如果方法還沒有被發(fā)現(xiàn),那么Perl放棄,并提出了一個運(yùn)行時異常。因此,要創(chuàng)建一個新的Employee類將繼承我們的Person類的方法和屬性,我們簡單的代碼:保持將此程式碼放入Employee.pm#!/usr/bin/perl package Employee; use Person; use strict; our @ISA = qw(Person); # inherits from Person Employee類的所有方法和屬性繼承自Person類,你可以用它如下:使用main.pl文件來測試它#!/usr/bin/perl use Employee; $object = new Employee( "Mohammad", "Saleem", 23234345); # Get first name which is set using constructor. $firstName = $object->getFirstName(); print "Before Setting First Name is : $firstName\n"; # Now Set first name using helper function.- by www.yiibai.com $object->setFirstName( "Mohd." ); # Now get first name set by helper function. $firstName = $object->getFirstName(); print "After Setting First Name is : $firstName\n"; This will produce following result First Name is Mohammad Last Name is Saleem SSN is 23234345 Before Setting First Name is : Mohammad Before Setting First Name is : Mohd. 方法重載 子類Employee繼承了所有的方法從父類Person.但是,如果你想在你的子類中重寫這些方法,那么你可以實現(xiàn)。在子類中,可以添加額外的函數(shù)。它可以做如下:修改Employee.pm文件:#!/usr/bin/perl package Employee; use Person; use strict; our @ISA = qw(Person); # inherits from Person # Override constructor sub new { my ($class) = @_; # Call the constructor of the parent class, Person. my $self = $class->SUPER::new( $_[1], $_[2], $_[3] ); # Add few more attributes $self->{_id} = undef; $self->{_title} = undef; bless $self, $class; return $self; } # Override helper function sub getFirstName { my( $self ) = @_; # This is child class function. print "This is child class helper function\n"; return $self->{_firstName}; } # Add more methods sub setLastName{ my ( $self, $lastName ) = @_; $self->{_lastName} = $lastName if defined($lastName); return $self->{_lastName}; } sub getLastName { my( $self ) = @_; return $self->{_lastName}; } 1; 現(xiàn)在把下面的代碼到main.pl和執(zhí)行它#!/usr/bin/perl use Employee; $object = new Employee( "Mohammad", "Saleem", 23234345); # Get first name which is set using constructor. $firstName = $object->getFirstName(); print "Before Setting First Name is : $firstName\n"; # Now Set first name using helper function. $object->setFirstName( "Mohd." ); # Now get first name set by helper function. $firstName = $object->getFirstName(); print "After Setting First Name is : $firstName\n"; This will produce following result First Name is Mohammad Last Name is Saleem SSN is 23234345 This is child class helper function Before Setting First Name is : Mohammad This is child class helper function After Setting First Name is : Mohd. 默認(rèn)自動加載 Perl提供了一個功能,你不會在其他許多編程語言找到:默認(rèn)的子程序。 如果你定義了一個函數(shù)調(diào)用AUTOLOAD(),那么任何未定義的子程序的調(diào)用將調(diào)用AUTOLOAD()函數(shù)。在此子程序$ AUTOLOAD缺少的子程序的名稱。 這個功能是非常有用的錯誤處理的目的。下面是一個例子實現(xiàn)的AUTOLOAD,你可以使用自己的方式實現(xiàn)這個函數(shù)。 sub AUTOLOAD { my $self = shift; my $type = ref ($self) || croak "$self is not an object"; my $field = $AUTOLOAD; $field =~ s/.*://; unless (exists $self->{$field}) { croak "$field does not exist in object/class $type"; } if (@_) { return $self->($name) = shift; } else { return $self->($name); } } 析構(gòu)函數(shù)和垃圾收集 如果你已經(jīng)編程使用對象之前,而你將意識到需要創(chuàng)建一個析構(gòu)函數(shù)。當(dāng)你使用完要釋放分配的內(nèi)存對象。Perl自動為您盡快的對象超出作用域。 如果你想實現(xiàn)你的析構(gòu)函數(shù)關(guān)閉文件,或做一些額外的處理,那么你需要定義一個特殊的方法,命名為destroy。 此方法會被調(diào)用的對象只是在Perl之前釋放分配給它的內(nèi)存。 在其他方面,就像其他DESTROY方法,可以操作任何你喜歡對象,以便正確地關(guān)閉它。析構(gòu)函數(shù)的方法是簡單地一個成員函數(shù)(子程序)命名的破壞都會被自動調(diào)用當(dāng)對象的引用變量超出了作用域。 當(dāng)對象引用的變量是未定義 當(dāng)腳本結(jié)束 當(dāng)Perl解釋器終止 有關(guān)實例:package MyClass; ... sub DESTROY { print " MyClass::DESTROY called\n"; } 另一種面向?qū)ο髮嵗?這里是另一個很好的例子,這將有助于你了解面向?qū)ο蟮母拍頟erl。把這個源代碼轉(zhuǎn)換成任何文件,并執(zhí)行它。#!/usr/bin/perl # Following is the implementation of simple Class. package MyClass; sub new { print " MyClass::new called\n"; my $type = shift; # The package/type name my $self = {}; # Reference to empty hash return bless $self, $type; } sub DESTROY { print " MyClass::DESTROY called\n"; } sub MyMethod { print " MyClass::MyMethod called!\n"; } # Following is the implemnetation of Inheritance. package MySubClass; @ISA = qw( MyClass ); sub new { print " MySubClass::new called\n"; my $type = shift; # The package/type name my $self = MyClass->new; # Reference to empty hash return bless $self, $type; } sub DESTROY { print " MySubClass::DESTROY called\n"; } sub MyMethod { my $self = shift; $self->SUPER::MyMethod(); print " MySubClass::MyMethod called!\n"; } # Here is the main program using above classes. package main; print "Invoke MyClass method\n"; $myObject = MyClass->new(); $myObject->MyMethod(); print "Invoke MySubClass method\n"; $myObject2 = MySubClass->new(); $myObject2->MyMethod(); print "Create a scoped object\n"; { my $myObject2 = MyClass->new(); } # Destructor is called automatically here #by www.yiibai.com print "Create and undef an object\n"; $myObject3 = MyClass->new(); undef $myObject3; print "Fall off the end of the script...\n"; # Remaining destructors are called automatically here?
總結(jié)
以上是生活随笔為你收集整理的浅谈Perl的类、包、模块与面对对象编程的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: [Angularjs]过滤器
- 下一篇: 第二阶段—个人工作总结03