php面向对象之多态(1)

来源:互联网 发布:淘宝商城女装新款复古 编辑:程序博客网 时间:2024/05/28 15:41

利用java来引入多态

买一个手电筒(说明书上写的手电筒只能装红玻璃),和几个不同颜色的玻璃片,目的是装上不同的玻璃片,显示不同的颜色

public class PolyTest{    public static void main(String[] args)    {        Light light = new Light();        RedGlass rg = new RedGlass();        BlueGlass bg = new BlueGlass();        light.ons(rg);        light.ons(bg);  // I want to show blue light;    }}class Light    //手电筒{    public void ons(RedGlass red)  //对应了说明书上写的只能装红玻璃    {        red.display();    }}class RedGlass  //红玻璃{     public void display()    {        System.out.println("red light");    }}class BlueGlass   //蓝玻璃{    public void display()    {        System.out.println("BlueGlass");    }}/**这样一段代码,在java中 编译通不过.原因是:    public void ons(RedGlass red)    {        red.display();    }    ons方法, 指定了 接收的参数必须是  RedGlass,即红玻璃对象    因此,你传一个蓝光玻璃,不行!强类型语言的一个特点,函数参数,函数的返回值,都是定死的.

这里写图片描述

改进上述java代码

让手电筒安装什么玻璃片就显示什么颜色
只需要让RedGlass和BlueGlass都继承一个父类Glass,说明书上声明安装玻璃Glass,不说明安装什么颜色的玻璃

上面程序的php实现

class Light {    // 开灯, 传一个玻璃参数    public function ons($g) {                $g->display();  // 用玻璃渲染颜色    }}class RedGlass {    public function display() {        echo '红光照耀<br />';    }}class BlueGlass {    public function display() {        echo '蓝光照耀<br />';    }}class GreenGlass {    public function display() {        echo '绿光照耀<br />';    }}class Pig {    public function display() {        echo '八戒下凡,哼哼坠地!<br />';    }}// 创建一个手电筒$light = new Light();// 创建3块玻璃$red = new RedGlass();$blue = new BlueGlass();$green = new GreenGlass();// 变红灯$light->ons($red);// 为蓝灯$light->ons($blue);// 变绿灯$light->ons($green);// 调用错了$pig = new Pig();$light->ons($pig);  //任然何以运行
分析 与java那段出错程序相比php没报错,因为PHP是弱类型动态语言.一个变量  $var = 8;$var = 'hello';$var = new Pig();一个变量,没有类型,你装什么变量都行.同理,传参,参数也没有强制类型.传什么参都行.所以,对于PHP动态语言来说,岂止是多态,简直是变态.又有专家说, 你这个太灵活了,简直变态,不能这么灵活. 否则我们就不说你多态.答:别急,我们不让php这么灵活还不行吗我对参数做类型限制总行了吧.见下一页

变态是因为没有限制类型,现在我们对参数做类型限制

限制类型的php

class Light {    // 此处,仿java,也加一个类名,做参数类型检测    public function ons(RedGlass $g) {          // 用玻璃渲染颜色        $g->display();    }}class RedGlass {    public function display() {        echo '红光照耀<br />';    }}class BlueGlass {    public function display() {        echo '蓝光照耀<br />';    }}class GreenGlass {    public function display() {        echo '绿光照耀<br />';    }}class Pig {    public function display() {        echo '八戒下凡,哼哼坠地!<br />';    }}$light = new Light();// 造手电筒$red = new RedGlass();// 造红玻璃$blue = new BlueGlass();// 造蓝玻璃$light->ons($red);// 红灯亮$light->ons($blue);// 出错:atchable fatal error: Argument 1 passed to Light::ons() must be an instance of RedGlass, instance of BlueGlass given

说明:
加了类型检测后,果然传蓝玻璃不行.
哲学: 子类是父类, 例:男人是人,白马是马,蓝玻璃是玻璃.
里氏代换: 原能用父类的场合,都可以用子类来代替.
解决:参数定为父类,传其子类.

php实现

class Light {    // 此处,仿java,也加一个类名,做参数类型检测    public function ons(RedGlass $g) {  //只能检测对象,这里即使传入int,也是按照对象看待        // 用玻璃渲染颜色        $g->display();    }}class Glass{    public function display(){}}class RedGlass extends Glass{    public function display() {        echo '红光照耀<br />';    }}class BlueGlass extends Glass {    public function display() {        echo '蓝光照耀<br />';    }}class Pig {    public function display() {        echo '八戒下凡,哼哼坠地!<br />';    }}$light = new Light();// 造手电筒$red = new RedGlass();// 造红玻璃$blue = new BlueGlass();// 造蓝玻璃$light->ons($red);// 红灯亮  成功$light->ons($blue);//蓝灯亮 成功// 猪八戒降生$pig = new Pig();$light->ons($pig);  //出错,要的是Glass对象,传入的却是pig对象

说明;
如果按PHP本身特点,不检测类型,本身就可以说是多态的,甚至变态的.

但是PHP5.3以后,引入了对于对象类型的参数检测,
注意 只能检测对象所属的类

其实,这对于PHP来说,限制了其灵活性,达到的java中多态的效果.

反思多态:
其实就是
只抽象的声明父类, 具体的工作由子类对象来完成
这样,不同的子类对象完成,有不同的特点

0 0