抽象类是指在 class 前加了 abstract 关键字且存在抽象方法(在类方法 function 关键字前加了 abstract 关键字)的类。php
抽象类不能被直接实例化。抽象类中只定义(或部分实现)子类须要的方法。子类能够经过继承抽象类并经过实现抽象类中的全部抽象方法,使抽象类具体化。编程
若是子类须要实例化,前提是它实现了抽象类中的全部抽象方法。若是子类没有所有实现抽象类中的全部抽象方法,那么该子类也是一个抽象类,必须在 class 前面加上 abstract 关键字,而且不能被实例化。
引用连接函数
接口(Interface)—— 定义行为this
抽象类(Abstract Class) —— 实现行为.net
具体类(class)——执行行为
引用连接设计
抽象类就是一个类的服务提供商,拥有众多服务,你不用必须用,当须要的时候你来用就能够,若是你以为不提供服务不满意,你还能够本身来作。code
抽象方法是必须实现的方法。就象动物都要呼吸。可是鱼用鳃呼吸,猪用肺呼吸。
动物类要有呼吸方法。怎么呼吸就是子类的事了。对象
引用连接blog
按照我目前的知识理解:继承
保持程序的一致性
抽象类限制了实现的方法,也是为了保持一致性
增长代码重用性,例如一些公共类不须要实现,只须要调用里面的方法就能够了。
如今有不少讨论和建议提倡用interface代替abstract类,二者从理论上能够作通常性的混用,可是在实际应用中,他们仍是有必定区别的。抽象类通常做为公共的父类为子类的扩展提供基础,这里的扩展包括了属性上和行为上的。而接口通常来讲不考虑属性,只考虑方法,使得子类能够自由的填补或者扩展接口所定义的方法,就像JAVA王子所说的事件中的适配器就是一个很好的应用。
用一个简单的例子,好比说一个教师,咱们把它做为一个抽象类,有本身的属性,好比说年龄,教育程度,教师编号等等,而教师也是分不少种类的,咱们就能够继承教师类而扩展特有的种类属性,而广泛属性已经直接继承了下来。
而接口呢~仍是拿教师作例子,教师的行为不少,除了和普通人相同的之外,还有职业相关的行为,好比改考卷,讲课等等,咱们把这些行为定义成无body的方 法,做为一个集合,它是一个interface。而教师张三李四的各自行为特色又有不一样,那么他们就能够扩展本身的行为body。从这点意义上来讲,interface偏重于行为。
<?php abstract class Shape{ //这是一个抽象类,不能实例化 protected $color; //抽象类里面通常都是使用protected来保护属性,这是封装的意义 public function __construct($color = 'red') { //抽象类可使用构造方法,主要是为了方便代码重用,构造方法里面也可使用默认参数,当没有配置参数的时候,就会使用默认的参数,写法如上 $this->color = $color; } public function getColor() { //只是为了演示须要的一个方法 return $this->color; } abstract public function getArea(); //构造方法是为了限制代码,对于继承这个构造类的子类,必须限制拥有这个构造方法,主要为了保持代码一致性。 } class Square extends Shape{ protected $length = 4; public function getArea() { return pow($this->$length, 2); } } class Circle extends Shape{ //这里由于没有构造方法getArea,因此代码容许会报错的。 } $shape = new Square(); var_dump($shape); ?>
抽象类不能被直接实例化,抽象类中只定义子类须要的方法,子类能够继承而且经过实现其中的抽象方法,使抽象类具体化。例如一个名为media的类,他是用于描述各类公开出版的共同性质,由于media不表示真实的实体,而是一些类似实体的泛化表示,因此不实例化,这样就须要声明为抽象类,而后再由各类的派生的Media类继承此抽象类
抽象类的每一个子类都必须实现抽象类中的全部抽象方法,或者把他们自身也声明为抽象方法。
扩展类不只仅负责简单实现抽象类的方法,还必须从新声明方法,新的方法不能比抽象方法的访问控制更严格,新的实现方法的参数个数应该和抽象方法的参数个数同样。
接口定义了实现某种服务的通常规范,声明了必须的函数和常量,可是不指定如何实现。关键是要创建必须实现的一组通常原则,只有知足了这些原则才能说实现了这个接口。
抽象类提供了具体实现的标准,而接口则是纯粹的模板。接口只能定义功能而不包含实现的内容。
任何实现接口的类都要实现接口中所定义的全部方法,不然类必须声明为abstract。
实现接口的类接受他的继承的类以及实现的接口的类型。
若是要建立一个模型,这个模型将由一些紧密相关的对象引用,就能够采用抽象类,若是要建立将由一些不想关的对象采用的功能,应该用接口。
若是必须从多个来源继承行为,就是用接口。
若是知道全部类都会共享一个公共的行为实现,就使用抽象类,并在其中实现行为。接口没法实现。
一个类只能extends一个父类,但能够贯彻多个接口。
接口类就是一个类的领导者,指明方向,子类必须完成它指定方法。
当有不少人一块儿开发一个项目时,可能都会去调用别人写的一些类,那你就会问,我怎么知道他的某个功能的实现方法是怎么命名的呢,这个时候php接口类就起到做用了,当咱们定义了一个接口类时,它里面的方式是下面的子类必须实现的,好比
interface Shop { public function buy($gid); public function sell($gid); public function view($gid); }
class BaseShop implements Shop { public function buy($gid) { echo '你购买了ID为 :' . $gid . '的商品'; } public function sell($gid) { echo '你购卖ID为 :' . $gid . '的商品'; } public function view($gid) { echo '你浏览了ID为 :' . $gid . '的商品'; } }
有时候,咱们须要设计一个物品,好比shape,这个shape有不一样的形状,有不一样的颜色,可做不一样的运动,等等。固然咱们能够把这些都放在一个类里面,但这样,如前面说的,只是过程编程,不是OO编程。你会说,像上面例子同样,作一个抽象类,而后在子类里实现全部的功能。好象不错,进步了。这样子类里面要实现形状,颜色,运动等功能,OK吗?记住,OO里面还有一条原则,为了最大程度的作到代码重用,一个类里最好只实现一个功能,也就是说,一个类作形状,一个类作颜色,一个类作运动 。这样若是其余的类要用到颜色的功能时,咱们就能够重用这个颜色类,同理,这样咱们能够很容易的重用运动类,形状类,等等。
但这样问题出来了,如今咱们要用到上面全部的功能,但又分散在三个类里面,怎么办?这时咱们就要用到抽象类和接口了。选定一个跟shape关联最大的一项–形状,把它作成抽象类, 其余两样,把它们作成接口,而后在子类里面extends一个抽象类,再implements两个接口就好了。如:
class Square extends Shape implements 颜色, 运动, ... { ... }
抽象类就是一个类的服务提供商,拥有众多服务,你不用必须用,当须要的时候你来用就能够,若是你以为不提供服务不满意,你还能够本身来作。
这里是一个例子,想上面同样我定义了一个商店类,抽所了它全部像的部分,买(buy),卖(sell),看(view),而且抽象类里都实现了这些方法,那么继承它的子类就自动得到了这些方法,子类就作它本身独特的东西,减小代码的重复,提升复用性。
abstract class BaseShop { public function buy($gid) { echo '你购买了ID为 :' . $gid . '的商品'; } public function sell($gid) { echo '你购卖ID为 :' . $gid . '的商品'; } public function view($gid) { echo '你浏览了ID为 :' . $gid . '的商品'; } } class BallShop extends BaseShop { var $itme_id = null; public function __construct() { $this->itme_id = 2314; } public function open() { $this->sell($this->itme_id); } }
在抽象类里面设置抽象方法
在oo设计时,会把一些通用的方法放在一个类里,但考虑到子类继承时的差别性,又不能把它事先实现,就只好用到这个抽象类或接口了。这里很清楚的显示了在抽象类里,咱们贯彻了设原用到点setCenter()的方法,这样,当子类继承它时,就不用再重复写这个设原点的方法了。那么为何draw的方法要设定成抽象方法呢?这是由于不一样的子类要用不一样的实现方法。
abstract class Shape { function setCenter($x, $y) { $this->x = $x; $this->y = $y; } abstract function draw(); protected $x, $y; }
参考:http://chengxudaren.com/index.php?act=article&op=detail&a_id=152