php父类与接口的一个小例子——引用自韩顺平的php视频
<?php /* 父类 老猴子 */ class Monkey { public $name; public $age; public function __construct($name, $age) { $this->name = $name; $this->age = $age; echo "我叫{$this->name},今年{$this->age}岁。<br />\n"; } public function climb() { echo "我会爬树!<br />\n"; } } /* 接口 鸟儿提供的一个飞翔接口 */ interface iFly { public function fly(); } /* 接口 鱼儿提供的一个游泳接口 */ interface iSwim { public function swim(); } /* 子类 小猴子是老猴子生的,并且它希望学到飞翔和游泳的本领 */ class LittleMonkey extends Monkey implements iFly, iSwim { // 通过自身努力实现飞翔的方法 public function fly() { echo "翻个跟斗,十万八千里!<br />\n"; } // 通过自身努力实现游泳的方法 public function swim() { echo "哈哈,铁掌水上漂!<br />\n"; } } /* 飞机类 也可以实现飞的功能 */ class Airplane implements iFly { public function fly() { echo "飞机在飞!<br />\n"; } } /* 游轮类 也可以实现游泳的功能 */ class Ship implements iSwim { public function swim() { echo "游轮航行!<br />\n"; } } // 先测试一下这只小猴子 $monkey = new LittleMonkey("孙悟空", 800); $monkey->climb(); $monkey->fly(); $monkey->swim(); // 测试飞机和游轮 $plane = new Airplane(); $plane->fly(); $ship = new Ship(); $ship->swim(); echo "<br/>\n"; /* 小猴子不用学爬树就能直接调用climb()方法,继承的作用体现了出来 */ /* 但是接口的作用并不明显,三个类分别实现了接口中定义的方法才具有了特定的功能 */ /* 目前来看接口只实现了一个规范的作用 */ /* 正因为有了这种规范才能衍生出后面的功能 */ /* 航展类 */ class Airshow { public function __construct() { echo "珠海航展正在进行中!<br/>\n"; } // 天高任鸟飞 public function showAircraft(iFly $aircraft) { $aircraft->fly(); } } /* 游泳博览会 */ class SwimmingExpo { public function __construct() { echo "游泳博览会正在进行中!<br/>\n"; } // 海阔凭鱼跃 public function showSwimming(iSwim $swimmer) { $swimmer->swim(); } } // 开始航展 $airshow = new Airshow(); $airshow->showAircraft(new LittleMonkey("孙悟空", 800)); // 猴子先来展示 $airshow->showAircraft(new Airplane()); // 飞机也来秀一下 echo "<br/>\n"; // 游泳博览会开始了 $swimmingExpo = new SwimmingExpo(); $swimmingExpo->showSwimming(new LittleMonkey("孙悟空", 800)); // 猴子先来展示 $swimmingExpo->showSwimming(new Ship()); // 游轮也要秀一下 /* 说白了,接口就是为了简化、统一我们的调用。我们开航展、博览会是不是很简单? */ /* 就是一个固定的方法 + 一个实现了相应接口的对象 */ /* 这也是多态性的体现,我根据传进来的对象是猴子还是飞机,来让对象自己飞 */ /* 传进来是猴子,猴子就执行飞;传进来是飞机,飞机就执行飞 */ /* 再延伸一下就会发现一个易于扩展的好处 */ /* 假设航天飞机来了,只要建一个航天飞机的类并实现iFly接口和fly()方法 */ /* 航展上只要加一句$airshow->showAircraft(new 航天飞机()); 扩展便完成了,很简洁,很统一。*/ ?>
好奇一下,如果我不用接口,我想开一个航展,会怎么做呢?
<?php /* 普通飞机类 */ class Plane { // 没有接口的限制,任何函数名都可以 public function planeFly() { echo "普通飞机在飞!<br />\n"; } } /* 航天飞机类 */ class SpaceShuttle { // 没有接口的限制,任何函数名都可以 public function spaceShuttleFly() { echo "航天飞机在飞!<br />\n"; } } /* 航展类 */ class Airshow { public function __construct() { echo "珠海航展正在进行中!<br/>\n"; } // 展示普通飞机 public function showPlane() { $plane = new Plane(); $plane->planeFly(); } // 展示航天飞机 public function showSpaceShuttle() { $spaceShuttle = new SpaceShuttle(); $spaceShuttle->spaceShuttleFly(); } /* 注意:如果两种飞机的展示写在一个函数里面 */ /* 那么我们就只能进行全部展示而不能完成部分展示的功能了 */ } // 测试 $airshow = new Airshow(); $airshow->showPlane(); $airshow->showSpaceShuttle(); echo "<br/>\n"; /* 没有用接口我们也实现了同样的功能 */ /* 但是从规范性、代码冗余度、可扩展性上看,是不是差了好多呢? */ ?>