Perl 面向对象编程的两种实现和比较:
<pre name="code" class="html">https://www.ibm.com/developerworks/cn/linux/l-cn-perlobj/
Perl 面向对象编程的两种实现和比较: Perl 面向对象的实现有两种方式: 1.基于匿名散列 2.基于数组 Perl 作为一种成熟的“面向过程”的语言,同样也提供了对于面向对象编程的支持。 Perl 中有两种不同地面向对象编程的实现,一是基于匿名哈希表的方式,每个对象实例的实质就是一个指向匿名哈希表的引用。 在这个匿名哈希表中,存储来所有的实例属性。二是基于数组的方式,在定义一个类的时候,我们将为每一个实例属性创建一个数组, 而每一个对象实例的实质就是一个指向这些数组中某一行索引的引用。在这些数组中,存储着所有的实例属性。 面向对象的概念 实例 (instance):一个对象的实例化实现。 标识 (identity):每个对象的实例都需要一个可以唯一标识这个实例的标记。 实例属性 (instance attribute):一个对象就是一组属性的集合。 实例方法 (instance method):所有存取或者更新对象某个实例一条或者多条属性的函数的集合。 类属性(class attribute):属于一个类中所有对象的属性,不会只在某个实例上发生变化。 类方法(class method):那些无须特定的对性实例就能够工作的从属于类的函数。 基于匿名散列表的方法: [root@wx03 test]# cat Person.pm
package Person;
sub new {
my ($class,$name, $age) = @_; ##第一个参数为类名
my $r_object = {
"name" => $name,
"age" => $age
};
return $r_object;
}; sub change_name {
my ($self, $new_name) = @_; ##第一个参数为对象
$self->{name} = $new_name;
}
1;
[root@wx03 test]# cat t15.pl
unshift(@INC,"/root/test");
use Person;
my $object_person = Person->new( "Tommy", "22" ); use Data::Dumper;
my $var = Dumper($object_person);
print $var; print $object_person->{"name"};
print "\n";
print $object_person->{"age"};
print "\n"; Person::change_name ($object_person, "Tonny" );
print $object_person->{"name"};
print "\n"; [root@wx03 test]# perl t15.pl
$VAR1 = {
'name' => 'Tommy',
'age' => '22'
};
Tommy
22
Tonny
[root@
但是,现在的这个方案有一个致命的缺点,Perl 的编译器并不知道如何 new 函数所返回的指向匿名哈希表的引用属于哪个类(模块)。这样的话,如果要使用类中的实例方法,只能直接标出方法所属于的类(模块)的名字,并将引用作为方法的第一个参数传递给它,如清单 2 所示。 bless 以一个普通的指向数据结构的引用为参数,它将会把那个数据结构(注意:此处不是引用本身)标记为属于某个特定的包,
这样就赋予了这个匿名哈希表的引用以多态的能力。同时,我们使用箭头记号来直接调用那些实例方法 换而言之,如果使用箭头的方式调用一个函数,箭头左边的那个对象将作为相应子例程的第一个参数。 Perl 的实例方法的本质其实就是一个第一个参数碰巧为对象引用的普通子例程 类方法则是不依赖于任何特定实例的普通子例程。 与实例方法不同,我们使用 Person::calculate_person_number () 的形势来调用类方法。这样的话,指向匿名哈希表的引用将不会作为第一个调用参数传入,我们与不需要在包的子例程附加处理传入引用的代码。 类方法不需要对象作为第一个参数 [root@wx03 test]# cat Person.pm
package Person;
sub new {
my ($class,$name, $age) = @_;
my $r_object = {
"name" => $name,
"age" => $age
};
return $r_object;
}; sub change_name {
my ($self, $new_name) = @_;
$self->{name} = $new_name;
};
sub calculate_person_number {
return 999;
} ;
1; //访问类方法;
[root@wx03 test]# cat t16.pl
unshift(@INC,"/root/test");
use Person;
my $person_number = Person::calculate_person_number();
print "\$person_number is $person_number\n"; [root@wx03 test]# perl t16.pl
$person_number is 999 基于匿名散列表的方法中的继承: 考虑这样一个类的层次,我们定义一个 Employee 类,继承于基类 Person: Employee 类继承Person类: 我们将类名Person 放入包Emoloyee的ISA数组里, 这样当调用一个在包Employee中没有定义的函数时,Perl编译器会自动 在Person类寻找这个函数。
Perl 面向对象编程的两种实现和比较:的更多相关文章
- 在 Perl看来, 字符串只有两种形式. 一种是octets, 即8位序列, 也就是我们通常说的字节数组. 另一种utf8编码的字符串, perl管它叫string. 也就是说: Perl只熟悉两种编
在 Perl看来, 字符串只有两种形式. 一种是octets, 即8位序列, 也就是我们通常说的字节数组. 另一种utf8编码的字符串, perl管它叫string. 也就是说: Perl只熟悉两种编 ...
- perl 面向对象编程
今天看到一个perl面向对象编程的例子,充分体现了如何对数据进行封装: 自己模仿写一个读取配置文件的例子, 配置文件的内容如下 samtools_binary = /usr/bin/samtools ...
- javascript面向对象编程的3种常见封装形式解析
javascript如何才能脱离函数式编程,拥抱面向对象编程呢,常见的有3种形式,其它形式可以说都是这3种的变种. 1.直接定义对象直接量的形式 var Util={ getType: ...
- Go -- 并发编程的两种限速方法
引子 golang提供了goroutine快速实现并发编程,在实际环境中,如果goroutine中的代码要消耗大量资源时(CPU.内存.带宽等),我们就需要对程序限速,以防止goroutine将资源耗 ...
- golang并发编程的两种限速方法
引子 golang提供了goroutine快速实现并发编程,在实际环境中,如果goroutine中的代码要消耗大量资源时(CPU.内存.带宽等),我们就需要对程序限速,以防止goroutine将资源耗 ...
- 异步编程的两种模型,闭包回调,和Lua的coroutine,到底哪一种消耗更大
今天和人讨论了一下CPS变形为闭包回调(典型为C#和JS),以及Lua这种具有真正堆栈,可以yield和resume的coroutine,两种以同步的形式写异步处理逻辑的解决方案的优缺点.之后生出疑问 ...
- <编程>比较两种素数表生成算法+计算程序运行时间+通过CMD重定向测试程序
最近学习加密算法,需要生成素数表,一开始使用简单的循环,从2开始判断.代码如下: #include<iostream> #include<cstdio> #include< ...
- Android 编程下两种方式注册广播的区别
常驻型广播 常驻型广播,当你的应用程序关闭了,如果有广播信息来,你写的广播接收器同样的能接收到,它的注册方式就是在你应用程序的AndroidManifast.xml 中进行注册,这种注册方式通常又被称 ...
- 转 Android 编程下两种方式注册广播的区别
常驻型广播 常驻型广播,当你的应用程序关闭了,如果有广播信息来,你写的广播接收器同样的能接收到,它的注册方式就是在你应用程序的AndroidManifast.xml 中进行注册,这种注册方式通常又被称 ...
随机推荐
- Exploring the MapBox stack: MBTiles, TileJSON, UTFGrids and Wax
转自:http://blog.thematicmapping.org/2012/11/exploring-mapbox-stack-mbtiles-tilejson.html In my last b ...
- BZOJ 1787: [Ahoi2008]Meet 紧急集合( 树链剖分 )
这道题用 LCA 就可以水过去 , 但是我太弱了 QAQ 倍增写LCA总是写残...于是就写了树链剖分... 其实也不难写 , 线段树也不用用到 , 自己YY一下然后搞一搞就过了...速度还挺快的好像 ...
- java.lang.NoClassDefFoundError: org.ksoap2.transport.HttpTransportSE异常处理
原因就是没有打包进去 因为引用进去 编译时没出出现问题 解决如下
- ZOJ 2794 Just Pour the Water 【矩阵快速幂】
给你n个杯子,每次有特定的到水规则,倒m次请问最后每个被子里还有多少水 我们很容易发现每次变化的规则相同,那么可以set 一个矩阵存放 然后多次倒水就相当于矩阵相乘,在m 范围达到(1<= M ...
- 窗体区域绘制问题WS_CLIPCHILDREN与WS_CLIPSIBLINGS
WS_CLIPCHILDREN,使得父窗体在绘制时留出其上的子窗体的位置不去画它,而那片区域留着子窗体去画.WS_CLIPSIBLINGS,必须用于子窗体,使得该子窗体在收到WM_PAINT时同时令其 ...
- Android studio多个项目之间怎么实现快速切换?
Android studio多个项目之间怎么实现快速切换?Android studio中打开的项目太多了,想切换到一个项目很麻烦,怎么才能快速切换到另一个项目中呢?请看下文详细介绍 在对Android ...
- PHP 重载 __call() _callStatic方法
在C++和java中,可以函数参数的个数或类型来进行重载.但php是弱类型的语言,无法采用传统的方法.若下面这样: class Person{ function fun1($a) { echo 'fu ...
- smarty 截取字符串,调用php中的方法,foreach循环
1.smarty截取字符串 html中的代码 <{$content|truncate:30:"..."}> ...
- perl 5.22手动安装Mysql DBI和DBD
mysql 手动安装DBI 和DBD: DBI版本: [root@dr-mysql01 DBD-mysql-4.033]# perl -MDBI -le 'print $DBI::VERSION;' ...
- 一步一步重写 CodeIgniter 框架 (7) —— Controller执行时将 Model获得的数据传入View中,实现MVC
1. 实现过程 1) 上一节讲述了 View 视图的加载过程,它是在 Loader 类中加载的,并通过 Include 语句进行包含.那么为了在 View 中传递变量,只需要在 include 语句所 ...