算法提高程序运行的速度,而设计模式提高编程的速度。
php是面向对象的脚本语言,而我们都知道,面向对象的语言具有三大特性:封装,继承,多态。
抽象类和接口
抽象/Abstraction
一个类中,只要有一个抽象方法,这个类必须被声明为抽象类。
抽象方法在子类中必须被重写。
其实抽象类和接口类有一部分很像,记得在哪里看见这样一句话,抽象类就把类像的部分抽出来,
如,鲸鱼和鲤鱼,这两个事物在动物的视角上,有明确的区分界限,属于不同的动物;但是在水生动物的视角上,他们属于同一种动物的抽象。
合理的对问题进行抽象,构造模型,将更容易通过编程来解决问题。
记住:抽象是编程解决问题的基础,越复杂的问题,越需要一开始就对问题进行抽象,而不是直接写代码。
抽象类是一个编程概念,PHP中叫Abstract Classes。在设计模式中,抽象类不能够被实例化/初始化,但是可以依靠具体类的继承(extends )来实现。
接口/Interface
PHP也支持面向过程编程概念中的接口,PHP支持在接口中定义常量,但是不支持抽象变量。关键词implements 实现接口。
接口中的所有方法都要求是抽象方法,所以就不需要在方法前使用abstract关键字标识了。而且在接口中也不需要显式地使用public访问权限进行修饰,因为默认权限就是public的,也只能是公有的。
PHP接口类interface就是一个类的领导者,指明方向,子类必须完成它指定方法。
interface 接口名称{ //使用interface关键字声明接口
常量成员 //接口中的成员属性只能是常量,不能是变量
抽象方法 //接口中的所有方法必须是抽象方法,不能有非抽象的方法存在
}
?>
下面同样用鲸鱼的例子来讲述:
interface IAction {
public function eat($food);
public function swim();
}
?>
抽象类vs接口
上面的抽象类和接口的例子,看上去是不是类似?事实上,对于PHP编程来说,抽象类可以实现的功能,接口也可以实现。
抽象类和接口的区别,不在于编程实现,而在于程序设计模式的不同。
一般来讲,抽象用于不同的事物,而接口用于事物的行为。
如:水生生物是鲸鱼的抽象概念,但是水生生物并不是鲸鱼的行为,吃东西才是鲸鱼的行为。
对于大型项目来说,对象都是由基本的抽象类继承实现,而这些类的方法通常都由接口来定义。
此外,对于事物属性的更改,建议使用接口,而不是直接赋值或者别的方式。
在学习PHP面向对象时,都会在抽象类与接口上迷惑,作用差不多为什么还那么容易混淆,何不留一去一?但是事实上两者的区别还是很大的,如果能够很好地运用PHP的两个方法,面向对象的程序设计将会更加合理、清晰高效。
对接口的使用方式是通过关键字implements来实现的,而对于抽象类的操作是使用类继承的关键字exotends实现的,使用时要特别注意。
接口没有数据成员,但是抽象类有数据成员,抽象类可以实现数据的封装。
接口没有构造函数,抽象类可以有构造函数。
接口中的方法都是public类型,而抽象类中的方法可以使用private、protected或public来修饰。
一个类可以同时实现多个接口,但是只能实现一个抽象类。
PHP的抽象类、接口的区别和选择
相同点:(注意抽象方法没有方法体,而且方法结束使用 ; 号,非抽象方法必须有方法体即{},可以不写具体内容)函数体内不能写任何东西,连两个大括号都不能写!!!如:function getName();这样就行了
封装
封装/Encapsulation
对事物的封装是指,将事物进行抽象后,提供抽象概念的实现的具体方法。
听起来很拗口,还是举鲸鱼的例子。
对于鲸鱼来说,需要吃东西这个行为,吃本身是一个抽象的概念,因为具体到怎么吃,是咀嚼和消化的过程,甚至如何咀嚼和消化也是不可见的。对外部而言,可见的只是吃这一个接口,如何吃、怎么吃,是被封装在了鲸鱼的实现中。
甚至可以说,消化系统,被封装到了鲸鱼这个对象中,对外部不可见,仅仅鲸鱼自己可见。
封装方法
和别的程序设计语言一样,PHP也只是三种封装概念:Private,Protected,Public。
私有/Private
私有的概念是,仅仅对象内部可见,外部不可见
保护/Protected
保护的概念是,仅仅是自身类和继承类可见,这个关键字的用途主要是防止滥用类的派生,另外三方库编写的时候会用到,防止误用。
继承
继承/Inheritance
还是用动物、鲸鱼和鲤鱼来举例:
abstract class Animal {
protected $name;
protected function chew($food) {
echo $this->name . " is chewing " . $food . ".\n";
}
protected function digest($food) {
echo $this->name . " is digesting " . $food . ".\n";
}
}
class Whale extends Animal {
public function __construct() {
$this->name = "Whale";
}
public function eat($food) {
$this->chew($food);
$this->digest($food);
}
}
class Carp extends Animal {
public function __construct() {
$this->name = "Carp";
}
public function eat($food) {
$this->chew($food);
$this->digest($food);
}
}
$whale = new Whale();
$whale->eat("fish");
$carp = new Carp();
$carp->eat("moss");
?>
运行一下:
$ php Inheritance.php
Whale is chewing fish.
Whale is digesting fish.
Carp is chewing moss.
Carp is digesting moss.
对于一个好的程序设计,需要:
类和类之间应该是低耦合的。
继承通常是继承自抽象类,而不是具体类。
通常直接继承抽象类的具体类只有一层,在抽象类中用protected来限定。
Summary
合理的继承对于好的程序设计同样是必不可少的,结合abstract和protected,能让你编写出结构清晰的代码。
继承权限:private、protected、public三者权限控制不能小于父类,可以扩大父类权限
多态
多态是指在面向对象中能够根据使用类的上下文来重新定义或改变类的性质和行为。
唯独这个多态,php体现的十分模糊。原因是php是弱类型语言。
interface IEat {
function eatFish();
function eatMoss();
}
class Whale implements IEat {
public function eatFish() {
echo "Whale eats fish.\n";
}
public function eatMoss() {
echo "Whale doesn't eat fish\n";
}
}
class Carp implements IEat {
public function eatFish() {
echo "Carp doesn't eat moss.\n";
}
public function eatMoss() {
echo "Carp eats moss.\n";
}
}
$whale = new Whale();
$whale->eatFish();
$whale->eatMoss();
$carp = new Carp();
$carp->eatFish();
$carp->eatMoss();
?>
运行一下:
$ php Inheritance.php
Whale eats fish.
Whale doesn't eat fish.
Carp eats moss.
Carp doesn't eat moss.