工具標籤
目錄
工具標籤
Perl 物件導向
Perl 中有兩種不同地物件導向程式設計的實作:
#一是基於匿名雜湊表的方式,每個物件實例的實質就是一個指向匿名哈希表的引用。在這個匿名哈希表中,儲存來所有的實例屬性。
二是基於數組的方式,在定義一個類別的時候,我們將為每一個實例屬性建立一個數組,而每一個物件實例的實質就是一個指向這些數組中某行索引的引用。在這些陣列中,儲存著所有的實例屬性。
物件導向基礎概念
物件有許多基礎概念,這裡我們接收三個:物件、類別和方法。
物件:物件是對類別中資料項的參考。 .
類別:類別是個Perl包,其中包含提供物件方法的類別。
方法:方法是個Perl子程序,類別名稱是其第一個參數。
Perl 提供了 bless() 函數,bless 是用來建構物件的, 透過 bless 把一個引用和這個類別名稱相關聯,回傳這個引用就建構出一個物件。
類別的定義
一個類別只是一個簡單的套件。
可以把一個包當作一個類別用,並且把包裡的函數當作類別的方法來用。
Perl 的套件提供了獨立的命名空間,所以不同套件的方法與變數名稱不會衝突。
Perl 類別的檔案後綴為 .pm。
接下來我們建立一個 Person 類別:
package Person;
類別的程式碼範圍到腳本檔案的最後一行,或到下一個 package 關鍵字前。
建立並使用物件
建立一個類別的實例(物件) 我們需要定義一個建構函數,大多數程式使用類別名稱作為建構函數,Perl 中可以使用任何名字。
你可以使用多種 Perl 的變數作為 Perl 的物件。大多數情況下我們會使用引用數組或哈希。
接下來我們為 Person 類別建立一個建構函數,使用了 Perl 的雜湊參考。
在建立物件時,你需要提供一個建構函數,它是一個子程序,傳回物件的參考。
實例如下:
package Person;
sub new
{
my $class = shift;
my $self = {
_firstName => shift,
_lastName => shift,
_ssn => shift,
};
# 输出用户信息
print "名字:$self->{_firstName}\n";
print "姓氏:$self->{_lastName}\n";
print "编号:$self->{_ssn}\n";
bless $self, $class;
return $self;
}接下來我們建立一個物件:
$object = new Person( "小明", "王", 23234345);
定義方法
Perl類別的方法只會是個Perl子程式而已,也即通常所說的成員函數。
Perl物件導向中Perl的方法定義不提供任何特別語法,但規定方法的第一個參數為物件或其被引用的套件。
Perl 沒有提供私有變量,但我們可以透過輔助的方式來管理物件資料。
接下來我們定義一個取得名字的方法:
sub getFirstName {
return $self->{_firstName};
}同樣也可以這麼寫:
sub setFirstName {
my ( $self, $firstName ) = @_;
$self->{_firstName} = $firstName if defined($firstName);
return $self->{_firstName};
}接下來我們修改Person.pm 檔案的程式碼,如下所示:
#!/usr/bin/perl
package Person;
sub new
{
my $class = shift;
my $self = {
_firstName => shift,
_lastName => shift,
_ssn => shift,
};
# 输出用户信息
print "名字:$self->{_firstName}\n";
print "姓氏:$self->{_lastName}\n";
print "编号:$self->{_ssn}\n";
bless $self, $class;
return $self;
}
sub setFirstName {
my ( $self, $firstName ) = @_;
$self->{_firstName} = $firstName if defined($firstName);
return $self->{_firstName};
}
sub getFirstName {
my( $self ) = @_;
return $self->{_firstName};
}
1;employee.pl 腳本程式碼如下:
#!/usr/bin/perl use Person; $object = new Person( "小明", "王", 23234345); # 获取姓名 $firstName = $object->getFirstName(); print "设置前姓名为 : $firstName\n"; # 使用辅助函数设置姓名 $object->setFirstName( "小强" ); # 通过辅助函数获取姓名 $firstName = $object->getFirstName(); print "设置后姓名为 : $firstName\n";
執行以上程式後,輸出結果為:
$ perl employee.pl 名字:小明 姓氏:王 编号:23234345 设置前姓名为 : 小明 设置后姓名为 : 小强
繼承
Perl 裡 類別方法透過@ISA陣列繼承,這個陣列裡麵包含其他套件(類別)的名字,變數的繼承必須明確設定。
多繼承就是這個@ISA陣列包含多個類別(套件)名字。
透過@ISA只能繼承方法,不能繼承資料。
接下來我們建立一個 Employee 類別繼承 Person 類別。
Employee.pm 檔案程式碼如下所示:
#!/usr/bin/perl package Employee; use Person; use strict; our @ISA = qw(Person); # 从 Person 继承
現在Employee 類別包含了Person 類別的所有方法和屬性,我們在main.pl 檔案中輸入以下程式碼,並執行:
#!/usr/bin/perl use Employee; $object = new Employee( "小明", "王", 23234345); # 获取姓名 $firstName = $object->getFirstName(); print "设置前姓名为 : $firstName\n"; # 使用辅助函数设置姓名 $object->setFirstName( "小强" ); # 通过辅助函数获取姓名 $firstName = $object->getFirstName(); print "设置后姓名为 : $firstName\n";
執行以上程式後,輸出結果為:
$ perl main.pl 名字:小明 姓氏:王 编号:23234345 设置前姓名为 : 小明 设置后姓名为 : 小强
方法重寫
上面實例中,Employee 類別繼承了Person 類,但如果Person 類別的方法無法滿足需求,就需要對其方法進行重寫。
接下來我們在Employee 類別中加入一些新方法,並重寫了Person 類別的方法:
#!/usr/bin/perl
package Employee;
use Person;
use strict;
our @ISA = qw(Person); # 从 Person 继承
# 重写构造函数
sub new {
my ($class) = @_;
# 调用父类的构造函数
my $self = $class->SUPER::new( $_[1], $_[2], $_[3] );
# 添加更多属性
$self->{_id} = undef;
$self->{_title} = undef;
bless $self, $class;
return $self;
}
# 重写方法
sub getFirstName {
my( $self ) = @_;
# 这是子类函数
print "这是子类函数\n";
return $self->{_firstName};
}
# 添加方法
sub setLastName{
my ( $self, $lastName ) = @_;
$self->{_lastName} = $lastName if defined($lastName);
return $self->{_lastName};
}
sub getLastName {
my( $self ) = @_;
return $self->{_lastName};
}
1;我們在main.pl 檔案中輸入以下程式碼,並執行:
#!/usr/bin/perl use Employee; $object = new Employee( "小明", "王", 23234345); # 获取姓名,使用修改后的构造函数 $firstName = $object->getFirstName(); print "设置前姓名为 : $firstName\n"; # 使用辅助函数设置姓名 $object->setFirstName( "小强" ); # 通过辅助函数获取姓名 $firstName = $object->getFirstName(); print "设置后姓名为 : $firstName\n";
執行上述程式後,輸出結果為:
$ perl main.pl 名字:小明 姓氏:王 编号:23234345 这是子类函数 设置前姓名为 : 小明 这是子类函数 设置后姓名为 : 小强
預設載入
如果在目前類別、目前類別所有的基底類別、還有UNIVERSAL 類別中都找不到要求的方法, 這時會再次尋找名為 AUTOLOAD() 的一個方法。如果找到了 AUTOLOAD,那麼就會 調用,同時設定全域變數 $AUTOLOAD 的值為缺少的方法的全限定名稱。
如果還不行,那麼 Perl 就宣告失敗並出錯。
如果你不想繼承基底類別的AUTOLOAD,很簡單,只需要一句:
sub AUTOLOAD;
析構函數及垃圾回收
當物件的最後一個引用釋放時,物件會自動析構。
如果你想在析構的時候做些什麼,那麼你可以在類別中定義一個名為"DESTROY"的方法。它將在適合的時機自動調用,並且按照你的意思執行額外的清理動作。
package MyClass;
...
sub DESTROY
{
print "MyClass::DESTROY called\n";
}Perl 會把物件的引用作為 唯一的參數傳遞給 DESTROY。注意這個引用是唯讀的,也就是說你不能透過存取$_[0] 來修改它。 (譯者註:參見 perlsub)但是物件本身(如 "${$_[0]" 或 "@{$_[0]}" 還有 "%{$_[0]}" 等等)還是可寫的。
如果你在析構器回傳之前重新 bless 了物件引用,那麼 Perl 會在析構器回傳之後接著呼叫你重新 bless 的那個物件的 DESTROY 方法。這可以讓你有機會呼叫基底類別或你指定的其它類別的析構器。需要說明的是,DESTROY 也可以手工調用,但是通常沒有必要這麼做。
在目前物件釋放後,包含在目前物件中的其它物件會自動釋放。
Perl 物件導向實例
我們可以透過以下實例來進一步理解Perl物件導向的應用:
#!/usr/bin/perl
# 下面是简单的类实现
package MyClass;
sub new
{
print "MyClass::new called\n";
my $type = shift; # 包名
my $self = {}; # 引用空哈希
return bless $self, $type;
}
sub DESTROY
{
print "MyClass::DESTROY called\n";
}
sub MyMethod
{
print "MyClass::MyMethod called!\n";
}
# 继承实现
package MySubClass;
@ISA = qw( MyClass );
sub new
{
print "MySubClass::new called\n";
my $type = shift; # 包名
my $self = MyClass->new; # 引用空哈希
return bless $self, $type;
}
sub DESTROY
{
print "MySubClass::DESTROY called\n";
}
sub MyMethod
{
my $self = shift;
$self->SUPER::MyMethod();
print " MySubClass::MyMethod called!\n";
}
# 调用以上类的主程序
package main;
print "调用 MyClass 方法\n";
$myObject = MyClass->new();
$myObject->MyMethod();
print "调用 MySubClass 方法\n";
$myObject2 = MySubClass->new();
$myObject2->MyMethod();
print "创建一个作用域对象\n";
{
my $myObject2 = MyClass->new();
}
# 自动调用析构函数
print "创建对象\n";
$myObject3 = MyClass->new();
undef $myObject3;
print "脚本执行结束...\n";
# 自动执行析构函数執行以上程序,輸出結果為:
调用 MyClass 方法 MyClass::new called MyClass::MyMethod called! 调用 MySubClass 方法 MySubClass::new called MyClass::new called MyClass::MyMethod called! MySubClass::MyMethod called! 创建一个作用域对象 MyClass::new called MyClass::DESTROY called 创建对象 MyClass::new called MyClass::DESTROY called 脚本执行结束... MyClass::DESTROY called MySubClass::DESTROY called
相關影片
熱AI工具
免費脫衣圖片
用於從照片中去除衣服的線上人工智慧工具。
人工智慧驅動的應用程序,用於創建逼真的裸體照片
人工智慧支援投資研究,做出更明智的決策
熱門文章
熱門話題
20522
7
13634
4
11967
4
9014
17
8507
7
熱門工具
好用且免費的程式碼編輯器
中文版,非常好用
強大的PHP整合開發環境
視覺化網頁開發工具
神級程式碼編輯軟體(SublimeText3)












![PHP實戰開發極速入門: PHP快速創建[小型商業論壇]](https://img.php.cn/upload/course/000/000/035/5d27fb58823dc974.jpg)
