Perl 中有两种不同地面向对象编程的实现:,接下来我们就来聊聊关于perl为什么运行不了?以下内容大家不妨参考一二希望能帮到您!

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

,