php oop----抽象类
抽象类机制使得子类可共用基类的某些信息,具体细节会留给子类,典型用在这样情形中,抽象类并不定义全部的方法,部分方法的实现推迟到子类继承抽象类时。它是介于接口和具体类间的一种构造元,接口中的操作都不给出实现---仅是声明,具体类中的所有操作都实现了。(我这里用到了操作和方法两个概念,他们的关系是:方法实现操作,操作是一个对象对外声称自己会提供的功能,方法是对这种声称的实现)。
可认为抽象类是部分类(partial classe),一般情况是一个抽象类中,抽象方法和具体方法的实现共存,但极端情况可以是:抽象类定义的所有方法可以全部是抽象方法或具体方法。不管哪种情况抽象类都必须被继承,不可以直接实例化他们(这一点像接口),抽象方法是缺乏方法体的方法原型(方法声明,或称方法签名),它包括:访问级别,function关键字,方法名称以及参数信息。方法签名不需要大括号,它很想C语言中的方法声明如: public function prototypeName($param);
DBC(designe by contract)——契约式编程设计
这种编程方式,是接口设计先行于类设计的,比如大家听到的面向接口设计,使用这种技术我们在构建应用系统时能够标识我们将要实现的功能。类似于架构师先构造一个计划,先于构造系统。
接口可形象地理解为对象的通讯协议,整个系统认为是一个对象图,对象间的联系就是方法调用,对对象发消息(对象通讯)就是调用对象的方法,而方法签名就是通讯协议(如果你从事过底层的套接字编程,那么那种通讯协议也是用来联通两个系统或应用的协议)。
大型系统,或多人开发的系统,开发组间往往先定义各个模块的接口,毕竟完全实现各个模块的方法的用时一般高于定义一个接口的用时,先定义接口会使我们在一个高抽象层次尽快看到系统的概貌,我们可以尽可能早的测试系统,比如如果只是实现了一部分接口那么我们可以用一些桩(用空方法体实现所有的接口操作声明)或者模拟对象(这些对象并不是真正的实现,他们只是根据接口的要求返还某个模拟的值)混同已经实现的模块来测试整个系统,不必等到所有的模块都实现后才测试。并且实现完成时使用接口规则很容易测试一个类的实现是否符合规范,最后对同一个接口的实现使得这些实现可以互相更换而不影响全局功能。总之面向接口的设计是一种很好的设计实践,很多大的企业都采用这种开发模式。
php 静态变量,成员和方法
静态变量,也被称为类变量,他的生存期比方法作用域的变量长,我们可以用静态变量来记录某个方法被调用的次数。方法级的变量生存期一般跟栈有关,而对象和类变量的作用域跟堆有关。可以认为静态变量的生存期等同于应用程序的生存期,且静态变量一般是全局可访问的。以上所说的是在别的语言中静态变量的知识。但是php中的静态变量跟C语言类似:
<?php
function staticVarTest(){
//声明一个静态变量,和一个局部变量
static $callTimes=0;
$localVar=0;
// echo "staticVarTest be called!";
$callTimes++;
$localVar++;
echo "localVar 局部变量的值是$localVar <br>";
echo "function staticVarTest has been called $callTimes 次<br>";
}
//以下调用上面的这个方法
staticVarTest();
staticVarTest();
staticVarTest();
staticVarTest();
?>
以上的这个方法其中定义了一个静态变量和局部变量,通过运行你可以发现局部变量在每次方法调用时都被赋予了原始值,而静态变量具有记忆效果,另外这里的静态变量仅能在本方法中访问,而全局变量是所有方法都可以访问的,同时被多个方法访问会导致安全问题,并且你可能还需要导入定义全局变量的文件。所以在某些情况下静态变量还是有用的。
接下来看看类中使用static关键字定义的变量或方法的特征。
一个类的静态成员是属于这个类的,如果你认为一个类能够概括所有该类的对象特征那么类变量就可以概括这个类的特征,比如 人类是伟大的,我是一个人。这句话里伟大的是形容人类的而不一定是形容某个人类的实例(我)。类实例一般是被该类的所有对象共享的,如你我他都应该为人类是伟大的而感到自豪。一定要区分实例变量和类变量,实例方法和类方法,一个类定义中带有static修饰符的变量或方法就是类级别的成员,否则就是实例级别的。只有类方法和类变量才可以用::域解析符,并且静态类成员要使用$符号。
class MyObject {
public static $myStaticVar=0;
function myMethod() {
self::$myStaticVar += 1;
echo self::$myStaticVar . "\n";
}
}
$varObj=new MyObject();
$varObj->myMethod();
注意到访问静态类变量我们使用了::符号,和C++语言中的一样 他被称为域作用解析符/域解析符(scope resolution operator)并且使用了$self关键字,$this表示对对象自己的引用,而$self表示对本类的引用。双冒号::还可用在parent关键字上。
比如你想在子类中调用某个基类的方法,(特别是增量式的扩充基类某个同名方法时)我们可以这样:
class MySubObject extends MyObject{
public function someFunc(){
echo 'someFunc of MySubObject been called!';
parent::myMethod();
}
//该方法覆盖父类的方法,并且重用了父类的同名方法
public function myMethod(){
parent::myMethod();
echo '<br>this code add from subClass';
}