1. 对象的简介
面向对象编程允许创建一些访问数据的接口,这些接口的创建方式独立于数据的实现方式。如果许多程序都是通过某个对象的方法来使用这个对象,那么我们可以随意改变数据的实现方式,而无须修改使用这些数据的程序。
2. 类的使用
要使用任何类,都必须先创建类的实例(也被称为类的对象)。类的构造函数(constructor)一般使用的名字是new,但perl也允许使用不同的名字作为构建函数的名字,这取决于具体的类。构造函数返回一个实例(对象)。
构造类的一个对象后,程序就可以用箭头运算符来调用对象的方法,如:
objectName à method ( arguments)
其中,objectName是指对象的名字;method是指方法;arguments是指传递给方法的参数。
3. 创建一个简单的类
接口定义了在用户眼中应该如何看待一个类。类的实现指一些基本的细节——类如何组织,以及类使用的数据类型和算法。
对于良好的软件工程来说,一条最重要的原则就是:接口与实现必须分离,这样更易于程序的修改。
内置函数bless的功能是接收一个引用,并将其转化为对象(注意:在perl中所有对象都是引用)。第一个参数是引用。对象的默认类型为当前包名。当有第二个参数时,就把这个对象变成由第二个参数指定的类型。
bless REF , CLASSNAME
构造函数中要做的第一件事就是决定创建对象的类型。在调用构造函数时有两种方法:调用时带有类型名( Type à new() 或 new Type)或是将其作用一个对象的方法,这个对象必须要与创建的对象相同 ( $object à new())。
my $type = shift();
my $class = ref ($type) || $type;
上面要么引用的类型,要么是传递的类型名。
4. 继承
经常会有一些新类从其他类派生(衍生)出来,这些新类可以使用原来那些类所拥有的属性和行为。同样,类也可以将其他类的对象包括进来,作为成员类。从现存的类中派生的新类,被称为继承。将其他类的对象包括进来作为成员类,称为合成(或聚集)。
@ISA数组用于从其它包导入变量和方法。
当调用一个方法的时候,如果当前类中并没有定义这个方法,Perl就会检索@ISA数组中的类,找出含有这个方法的类。
当你调用了调用者的一个类型为 classname 的方法 methname,Perl 将尝试六种不同的 方法来找出所用的子过程
a) 首先,Perl 在调用者自己的包里查找一个叫 classname::methname 的子过程。如果失败,则进入继承,并且进入步骤2
b) 第二步,Perl 通过检查 @classname::ISA 里列出的所有父包,检查从基类继承过来的方法,看看有没有parent::methname子过程。这种搜索是从左向右,递归的,由浅入深进行的。递归保证祖父类,曾祖父类,太祖父类等等类都进入搜索。
c) 如果仍然失败,Perl 就搜索一个叫 UNIVERSAL::methname 的子过程。
d) 这时,Perl 放弃 methname 然后开始查找 AUTOLOAD。首先,它检查叫做 classmane::AUTOLOAD 的子过程。
e) 如果上面的失败,Perl 则搜索所有在 @classname::ISA 里列出的 parent包,寻找任何 parent::AUTOLOAD 子过程。这样的搜索仍然是从左向右,递归的,由浅入深进行的。
f) 最后,Perl 寻找一个叫 UNIVERSAL::AUTOLOAD 的子过程。
5. 方法重载
perl可以在子类中对从超类(或称为基类)中继承的方法进行方法重载。当调用一个对象的方法时,perl首先试着在该对象所属的类中找到这个方法,如果没有找到,perl就会在该类的的基础类中继续查找。这就意味着如果在一个派生类中重新定义了一个继承下来的方法,perl会首先调用派生类中的版本,而不是被继承的基础类的版本——派生类的版本(或重载)优先于基础类版本。
6. 其他类关系:多重继承、合成和包容
多重继承:在派生类的@ISA数组中加入一个以上的类。
合成关系:又称为使用关系,类的一个对象可能有一个或多个属性是其他的类的对象。
包容关系:类的一个对象包容了其他对象的集合。
7. 基础类UNIVERSAL
从基础类UNIVERSAL中继承了用于查看一个对象继承了那些类以及对一个对象有哪些方法可用。
如果希望对每个类都增加一个函数,就可以直接把该函数加入到基础类UNIVERSAL中。
UNIVERSAL提供了isa和can方法。方法isa用于判断一个类是否继承了另一个类,而方法can判断一个类是否实现了某个特定的方法。
8. 封闭方法
使用深绑定和封闭将数据设为private。数据封装的封闭方法用到这样一个事实,即一个封闭模块中的变量在封闭之外是不可用的。
封闭的方法使得属性对于类是private的。不再像原先那样,把对象当作一个指向含有数据的三类标引用,而是把对象当成一个包含数据的封闭的引用。当调用函数时,构造函数创建一个散列表引用。然后构造函数创建一个封闭模块,当接收正确的参数时,该封闭模块会返回属性。
封闭模块的方法,首先把一个匿名子过程存放在一个文件范围的词法里:
# 声明私有方法
my $secret_door = sub {
my $self = shift;
...
};
然后,通过对函数引用进行解除来调用封闭模块,要使用&符号,和正确的参数。
9. 隐式函数
在perl中的隐式函数通常使用一个全由大写字母组成的名字来表示。
函数BEGIN是一个隐式函数,他的行为很像一个标准函数:可以被声明,而且函数前面的sub可以隐含。每次perl遇到一个BEGIN块时,它会自动执行该块。程序中显式调用BEGIN是一种错误。BEGIN函数按其声明时的顺序被调用,忽略所有的控制结构。通常BEGIN用于初始化全局变量并导入模块和环境参数。
隐式函数END,在程序结尾处最后一条语句执行完毕后立即运行。END函数的执行次序与BEGIN正好相反,最后声明的最先执行。程序中止后需要进行的所有例行工作都放到END函数中。
隐式函数DESTROY,在一个对象撤销时被调用——要么是在超出作用域范围时,要么在程序中止时。该函数被用于对那些使用了资源的对象进行一些清除工作。
10. AUTOLOAD函数
隐式函数中一个比较重要的函数是AUTOLOAD。如果一个方法被调用时,解释器无法从对象的类或其他各级基础类中找到该方法,perl通常会中止程序,并产生致命错误信息。而可以使用AUTOLOAD函数避免。如果没有找到一个方法,perl会查找该类(或其他基础类)中的AUTOLOAD函数。如果找到了AUTOLOAD函数就调用它,并且将一个特殊变量$AUTOLOAD设置成被调用方法的名字。AUTOLOAD可以用来截获其他致命错误,还可以用于避免对那些所完成的功能几乎相同的函数加以逐个声明。
11. 绑定函数
除了上述隐性函数以外,还有一些隐性函数,他们使用tie函数把变量绑定到某个类上。还可以用这些函数将类的实现对用户隐藏起来。当程序处理一个变量时,就调用一个隐性函数。例如,当把一个值赋给一个标量时,程序就调用了STORE函数,对该标量赋值。如果在类中定义自己的STORE函数,并且函数中使用了绑定函数tie,把一个变量绑定到该类上,就可以重载变量的STORE函数,对该标量提供各种不同的赋值功能。
tie函数有三个参数,第一个参数是被绑定的变量,第二个参数是变量要被绑定到的那个类,第三个参数是初始化数据列表。
tie (VARIABLE , CLASSNAME , LIST)<script type="text/javascript"> </script> <script type="text/javascript" src="http://pagead2.googlesyndication.com/pagead/show_ads.js"> </script>