tft每日頭條

 > 生活

 > perl為什麼運行不了

perl為什麼運行不了

生活 更新时间:2024-11-16 17:23:57

perl為什麼運行不了?Perl 中有兩種不同地面向對象編程的實現:,接下來我們就來聊聊關于perl為什麼運行不了?以下内容大家不妨參考一二希望能幫到您!

perl為什麼運行不了(Perl面向對象)1

perl為什麼運行不了

Perl 中有兩種不同地面向對象編程的實現:

  • 一是基于匿名哈希表的方式,每個對象實例的實質就是一個指向匿名哈希表的引用。在這個匿名哈希表中,存儲來所有的實例屬性。

  • 二是基于數組的方式,在定義一個類的時候,我們将為每一個實例屬性創建一個數組,而每一個對象實例的實質就是一個指向這些數組中某一行索引的引用。在這些數組中,存儲着所有的實例屬性。


面向對象基礎概念

面向對象有很多基礎概念,這裡我們接收三個:對象、類和方法。

  • 對象:對象是對類中數據項的引用。.

  • :類是個Perl包,其中含提供對象方法的類。

  • 方法:方法是個Perl子程序,類名是其第一個參數。

Perl 提供了 bless() 函數,bless 是用來構造對象的, 通過 bless 把一個引用和這個類名相關聯,返回這個引用就構造出一個對象。


類的定義

一個類隻是一個簡單的包。

可以把一個包當作一個類用,并且把包裡的函數當作類的方法來用。

定義方法

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 packagePerson; subnew{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;}subsetFirstName{my($self, $firstName) = @_; $self->{_firstName} = $firstNameifdefined($firstName); return$self->{_firstName};}subgetFirstName{my($self) = @_; return$self->{_firstName};}1;

employee.pl 腳本代碼如下:

實例

#!/usr/bin/perluse Person; $object = newPerson("小明", "王", 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/perlpackageEmployee;use Person;use strict;our@ISA = qw(Person); # 從 Person 繼承

現在 Employee 類包含了 Person 類的所有方法和屬性,我們在 main.pl 文件中輸入以下代碼,并執行:

實例

#!/usr/bin/perluse Employee; $object = newEmployee("小明", "王", 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/perlpackageEmployee;use Person;use strict;our@ISA = qw(Person); # 從 Person 繼承# 重寫構造函數subnew{my($class) = @_; # 調用父類的構造函數my$self = $class->SUPER::new($_[1], $_[2], $_[3]); # 添加更多屬性$self->{_id} = undef; $self->{_title} = undef; bless$self, $class; return$self;}# 重寫方法subgetFirstName{my($self) = @_; # 這是子類函數print"這是子類函數\n"; return$self->{_firstName};}# 添加方法subsetLastName{my($self, $lastName) = @_; $self->{_lastName} = $lastNameifdefined($lastName); return$self->{_lastName};}subgetLastName{my($self) = @_; return$self->{_lastName};}1;

我們在 main.pl 文件中輸入以下代碼,并執行:

實例

#!/usr/bin/perluse Employee; $object = newEmployee("小明", "王", 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# 下面是簡單的類實現packageMyClass; subnew{print"MyClass::new called\n"; my$type = shift; # 包名my$self = {}; # 引用空哈希returnbless$self, $type; }subDESTROY{print"MyClass::DESTROY called\n";}subMyMethod{print"MyClass::MyMethod called!\n";}# 繼承實現packageMySubClass; @ISA = qw( MyClass ); subnew{print"MySubClass::new called\n"; my$type = shift; # 包名my$self = MyClass->new; # 引用空哈希returnbless$self, $type; }subDESTROY{print"MySubClass::DESTROY called\n";}subMyMethod{my$self = shift; $self->SUPER::MyMethod(); print" MySubClass::MyMethod called!\n";}# 調用以上類的主程序packagemain; 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 calledMyClass::MyMethod called!調用 MySubClass 方法MySubClass::new calledMyClass::new calledMyClass::MyMethod called! MySubClass::MyMethod called!創建一個作用域對象MyClass::new calledMyClass::DESTROY called創建對象MyClass::new calledMyClass::DESTROY called腳本執行結束...MyClass::DESTROY calledMySubClass::DESTROY called

,

更多精彩资讯请关注tft每日頭條,我们将持续为您更新最新资讯!

查看全部

相关生活资讯推荐

热门生活资讯推荐

网友关注

Copyright 2023-2024 - www.tftnews.com All Rights Reserved