对码当歌,猿生几何?

PHP类的多态与封装

        nblogs-markdown">


title: PHP类的多态与封装
date: 2018-6-21
categories:

  • PHP学习笔记
    tags:

  • php

多态性(Polymorphism),简单的说就是同一操作作用于不同的类的实例上时,会产生不同的执行结果。

在软件设计中,多态使得应用程序更加模块化和可扩展。

多态性分两种:

  • 静态多态性:指一个同名函数或者一个类中的同名方法,根据参数列表(类型及个数)的不同来区别语义,即所谓的函数重载。但PHP不支持函数重载。

  • 动态多态性:指类的成员方法,能根据调用它的对象类型的不同,自动做出适应性调整,而且调整时发生在程序运行时。(PHP通过抽象类和接口技术来实现动态多态性)

子类覆盖父类

子类对继承自父类的方法进行“重写”,就是子类中定义一个同名的父类方法。
覆盖后若要使用父类原来的方法,需要使用关键字parent 和 域操作符::

parent::父类同名方法;

如果父类“很强势”,不想自己的方法别子类覆盖重写,可以使用final关键字来修饰该方法。

抽象类和抽象方法

抽象类是一种不能被实例化的类,只能作为父类被其他类继承。

与其他类一样抽象类也可以有属性和方法,但不同点在于,抽象类必须至少包含一个抽象方法。

所谓抽象方法,就是没有具体实现的方法,其对应的函数体为空。

抽象方法的细节只能在子类中实现,而且子类必须实现所继承的抽象类中的所有的抽象方法。

抽象类和抽象方法都用关键字abstract来定义,格式如下:

abstract class 抽象类名{
    //...
    abstract [public | protected] function 抽象方法名 ([方法参数]);
    //定义抽象方法
}

其中,抽象方法的访问控制修饰符只能是 public 或 protected 。

如果抽象方法声明为 public ,则子类中实现的方法也应声明为 public ;

如果抽象方法声明为 protected ,则子类中实现的方法既可以声明为 protected,也可以声明为 public。

抽象方法和抽象类的作用:
抽象方法和抽象类主要用于设计复杂的层次关系,这种层次关系要求子类都包含并重写某个特定的方法。

例如,人按社会分工可以分为学生、工人、商人等,每个人都要工作,只是岗位不同,学生要在学校听课,工人要在工地干活,商人要在店铺卖东西等。

如果把人作为一个抽象类,工作作为抽象方法,把学生、工人、商人作为继承该类的子类,那么工作这个方法在子类中的实现细节是不同的。

abstract class 人类{  //抽象类,不能被实例化,只能作为父类被其他类继承
    //...
    abstract function 工作();  //抽象方法,只定义没有具体内容
}

class 学生 extends 人类{
    //继承了人类这个抽象类,就必须实现人类中所有的抽象方法
    function 工作(){
        写作业
    }
}

class 工人 extends 人类{
    //继承了人类这个抽象类,就必须实现人类中所有的抽象方法
    function 工作(){
        干活
    }
}

接口

接口是一种多态技术。无论是普通类还是抽象类,都只能实现单继承,即一个子类只能继承一个父类。而要继承多个类就要通过接口(interface)来实现。

接口也可以看着是一种类,
只是这种类中可以定义常量,当不能定义属性变量;
可以定义方法,但方法必须为空,且方法必须为 public (可以省略,因为类的方法默认就是 public)

接口通过关键字 interface 来定义,格式如下:

interface 接口名{
    const 常量名 = 值;//只能定义常量,不能定义变量
    ...
    function 方法名([参数]); //只定义,没有具体内容
}

子类通过 implements 关键字来实现接口,格式如下:

class 子类名 implements 接口名{
    //子类实现细节
}

子类可以实现多个接口,接口名之间用逗号“,”连接。格式如下:

class 子类名 implements 接口名1, 接口名2, 接口名3{
    //子类实现细节
}

子类在实现接口时,必须实现接口中所有的方法。

思考:接口和抽象类抽象方法有什么异同点?
答:
相同点:
接口和抽象类中的方法都是定义而没有具体内容。
均只能作为父类被其他类继承。
子类均要实现抽象方法或接口中的所有方法。
接口 interface --- 子类 implements
抽象类 abstract --- 子类 ententds
不同点:
子类只能继承一个抽象类(子类只能单继承),子类可以有多个接口(可以看成多个父类)。
接口中只能定义常量而不能定义变量,而抽象类可以。