1.理解面向对象的概念php
面向对象软件的一个重要优势是支持和鼓励封装的能力。封装也叫数据隐藏。web
在面向对象的软件中,对象是一个被保存数据和操做这些数据的操做方法的惟1、可标识的集合。编程
对象能够按类进行分类。编程语言
面向对象的编程语言必须支持多态性,多态性的意思是指不一样的类对同一操做能够有不一样的行为。语言支持多态性,能够知道将哪一个操做应用于一个特定的对象。函数
多态性与其说是对象的特性,不如说是行为的特性。在PHP中,只有类的成员函数能够是多态的。this
例如,尽管自行车的“移动”和汽车的“移动”在概念上是类似的,可是移动一辆自行车和移动一辆汽车所包含的行为是彻底不一样的。一旦行为做用的对象肯定下来,动词“移动”就能够和一系列特定的行为联系起来。spa
继承容许咱们使用子类在类之间建立层次关系。子类将从它的超类继承属性和操做。3d
2.在PHP中建立类、属性和操做指针
当建立一个PHP类的时候,必须使用关键词“class”。code
2.1 类的结构
以下所示代码建立了一个名为“classname”的类,它具备两个属性$attribute1和$attribute2:
class classname{ public $attribute1; public $attribute2; }
经过在类定义中声明函数,能够建立类的操做。
class classname{ function operation1() { } function operation2($param1,$param2) { } }
2.2 构造函数
大多数类都有一种称为构造函数的特殊操做。当建立一个对象时,它将调用构造函数,一般,这将执行一些有用的初始化任务:例如,设置属性的初始值或者建立该对象须要的其余对象。
构造函数其名称必须是__construct()。这是PHP5中的变化。尽管能够手工调用构造函数,但其本意是在建立一个对象时自动调用。声明一个具备构造函数的类:
class classname{ function __construct($param){ echo “Constructor called with parameter ”.$param.”<br />”; } }
PHP支持函数重载,这就意味着能够提供多个具备相同名称以及不一样数量或类型的参数的函数。
2.3 析构函数
与构造函数相对的是析构函数。析构函数容许在销毁一个类以前执行一些操做或完成一些功能,这些操做或功能一般在全部对该类的引用都被重置或超出做用域时自动发生。
与构造函数的名称相似,一个类的析构函数名称必须是__destruct()。析构函数不能带有任何参数。
3.类的实例化
在声明一个类后,须要建立一个对象(一个特定的个体,即类的一个成员)并使用这个对象。这也叫建立一个实例或实例化一个类。可使用关键词“new”来建立一个对象。须要指定建立的对象是哪个类的实例,而且经过构造函数提供任何所需的参数。
以下所示的代码声明了一个具备构造函数、名为classname的类,而后又建立3个classname类型的对象。
class classname{ function _construct($param){ echo “Constructor called with parameter ”.$param.”<br />”; } } $a = new classname(“First”); $b = new classname(“Second”); $c = new classname();
运行发现如下报错:
$c的参数补上:
class classname{ function __construct($param){ echo "Constructor called with parameter ".$param."<br />"; } } $a = new classname("First"); $b = new classname("Second"); $c = new classname("");
4.使用类的属性
在一个类中,能够访问一个特殊的指针——$this。若是当前类的一个属性为$attribute,则当在该类中经过一个操做设置或访问该变量时,可使用$this->attribute来引用。
以下所示的代码说明了如何在一个类中设置和访问属性:
class classname{ public $attribute; function operation($param){ $this->attribute = $param; echo $this->attribute; } }
是否能够在类的外部访问一个属性是由访问修饰符来肯定的。
一般,从类的外部直接访问类的属性是糟糕的想法。面向对象方法的一个优势就是鼓励使用封装。能够经过使用__get()和__set()函数来实现对属性的访问。
若是不直接访问一个类的属性而是编写访问函数,那么能够经过一段代码执行全部访问。当最初编写访问函数时,访问函数可能以下所示:
class classname{ public $attribute; function __get($name){ return $this->$name; } function __set($name,$value){ $this->$name = $value; } }
以上代码为访问$attribute属性提供了最基本的功能。__get()函数返回了$attribute的值,而__set()函数只是设置了$attribute的值。
注意,__get()函数带有一个参数(属性的名称)而且返回该属性的值。__set()函数须要两个参数,分别是:要被设置值的属性名称和要被设置的值。
咱们并不会直接访问这些函数。这些函数名称前面的双下划线代表在PHP中这些函数具备特殊的意义,就像__construct()函数和__destruct()函数同样。
这些函数的工做原理是怎样的?若是实例化一个类:
$a = new classname();
能够用__get()函数和__set()函数来检查和设置任何属性的值。
若是使用以下命令:
$a -> $attribute = 5;
该语句将间接调用__set()函数,将$name参数的值设置为“attribute”,而$value的值被设置为5。必须编写__set()函数来完成任何所需的错误检查。
__get()函数的工做原理相似。若是在代码中引用:
$a -> attribute;
该语句将间接调用__get()函数,$name参数的值为“attribute”。咱们能够本身决定编写__get()函数来返回属性值。
咱们只使用一段代码来访问特定的属性。只有一个访问入口,就能够实现对要保存的数据进行检查,这样就能够确保被保存的数据是有意义的数据。
若是后来发现$attribute属性值应该是0到100之间,咱们就能够添加几行代码,在属性值改变以前进行检查:
function _set($name, $value){ if(($name=”attribute”)&&($value>=0)&&($value<=100)) $this->attribute = $value; }
经过单一的访问入口,能够方便地改变潜在的程序实现。
不管须要作什么样的改变,只要修改访问器函数便可。只要保证这个访问器函数仍然接收并返回程序的其余部分指望的数据类型,那么程序的其余部分代码就不会受影响。
5.使用private和public关键字控制访问
PHP支持以下3种访问修饰符:
· 默认选项是public。公有的属性或方法能够在类的内部和外部进行访问。
· private访问修饰符意味着被标记的属性或方法只能在类的内部进行访问。
· protected能够理解成位于private和public之间的关键字,后面会详细探讨。
6.类操做的调用
与调用属性大致上相同,可使用一样的方式调用类的操做。
若是有以下类:
class classname{ function operation1() { } function operation2($param1,param2) { } }
而且建立了一个类型为classname、名称为$a的对象,以下所示:
$a = new classname();
能够像调用其余函数同样调用操做:经过使用其名称以及将全部所需的参数放置在括号中。由于这些操做属于一个对象而不是常规的函数,因此须要指定它们所属的对象。对象名称的使用方法与对象属性同样,以下所示:
$a -> operation1(); $a -> operation2(12,”test”);
若是操做具备返回值,能够捕获到以下所示的返回数据:
$x = $a->operation1(); $y = $a->operation2(12,”test”);
7.在PHP中实现继承
继承是单方向的。子类能够从父类或超类继承特性,父类缺不能从子类继承特性。
7.1 经过继承使用private和protected访问修饰符控制可见性
可使用private和protected访问修饰符来控制须要继承的内容。 若是一个属性或方法被指定为private,它将不能被继承。
若是一个属性或方法被指定为protected,它将在类外部不可见(就像一个private元素),可是能够被继承。
考虑以下实例:
<?php class A{ private function operation1(){ echo "operation1 called"; } protected function operation2(){ echo "operation2 called"; } public function operation3(){ echo "operation3 called"; } } class B extends A{ function __construct(){ $this->operation1(); $this->operation2(); $this->operation3(); } } $b = new B; ?>
$this->operation1();这句将产生报错:
说明私有操做不能在子类中调用。
若是注释掉这一行,其余两个函数调用将正常工做。
protected函数能够被继承可是只能在子类内部使用。若是尝试在该文件结束处添加以下所示的代码:
$b->operation2();
将产生以下报错:
7.2 重载
在子类中,再次声明相同的属性和操做也是有效的,并且在有些状况下这将会是很是有用的。咱们可能须要在子类中给某个属性赋予一个与其超类属性不一样的默认值,或者给某个操做赋予一个与其超类操做不一样的功能。这就叫重载。
例如,若是有类A:
class A{ public $attribute = "default value"; function operation(){ echo "Something<br />"; echo "The value of \$attribute is ".$this->attribute."<br />"; } }
如今,若是须要改变$attribute的默认值,并为operation()操做提供新的功能,能够建立类B,它重载了$attribute和operation()方法,以下所示:
class B extends A{ public $attribute = "different value"; function operation(){ echo "Something else<br />"; echo "The value of \$attribute is ".$this->attribute."<br />"; } }
声明类B并不会影响类A的初始定义:
$a = new A(); $a -> operation();
这两行代码建立了类A的一个对象而且调用了它的operation()函数:
注意$this->后的变量不带$符。
若是建立了类B的一个对象:
$b = new B(); $b -> operation();
与子类中定义新的属性和操做并不影响超类同样,在子类中重载属性或操做也不会影响超类。
若是不使用替代,一个子类将继承超类的全部属性和操做。若是子类提供了替代定义,替代定义将有优先级而且重载初始定义。
parent关键字容许调用父类操做的最第一版本。例如,要从类B中调用A::operation,可使用以下所示的语句:
parent::operation();
可是,其输出结果倒是不一样的。虽然调用了父类的操做,可是PHP将使用当前类的属性值。
源码:
<?php class A { public $attribute = "default value"; function operation() { echo "Something<br />"; echo "The value of \$attribute is ".$this->attribute."<br />"; } } class B extends A { public $attribute = "different value"; function operation() { echo "Something else<br />"; echo "The value of \$attribute is ".$this->attribute."<br />"; } function Aoperation() { parent::operation(); } } $a = new A(); $a->operation(); $b = new B(); $b->Aoperation(); ?>
继承能够是多重的。能够声明一个类C,它继承了类B,所以继承了类B和类B父类的全部特性。类C还能够选择重载和替换父类的那些属性和操做。
7.3 使用final关键字禁止继承和重载
当在一个函数声明前面使用final关键字时,这个函数将不能被任何子类中被重载。也可使用final关键字来禁止一个类被继承。
7.4 PHP不支持多重继承
如题,每一个类只能继承一个父类。一个父类能够有多少个子类则并无限制。
7.5 实现接口
若是须要实现多重继承功能,在PHP中,能够经过接口。接口能够看做是多重继承问题的解决方法。
接口的思想是指定一个实现了该接口的类必须实现的一系列函数。例如,须要一系列可以显示自身的类。除了能够定义具备display()函数的父类,同时使这些子类都继承该父类并重载该方法外,还能够实现一个接口:
interface Displayable{ function display(); } class webPage implements Displayable{ function display(){ // ... } }
以上代码示例说明了多重继承的一种解决办法,由于webPage类能够继承一个类,同时又能够实现一个或多个接口。
若是没有实现接口中指定的方法,将产生一个致命错误。
整理自《PHP和MySQL Web》开发