PHP 进阶之 抽象类(abstract)、接口(interface)、Trait(特征)

抽象类

PHP 5 支持抽象类和抽象方法。定义为抽象的类不能被实例化。

  • 抽象方法只能在抽象类中,抽象类中可以包含非抽象方法
  • 被定义为抽象的方法只是声明了其调用方式(参数),不能定义其具体的功能实现
  • 继承一个抽象类的时候,子类必须定义父类中的所有抽象方法,另外,这些方法的访问控制必须和父类中一样(或者更为宽松)。

抽象方法给我们提供了一个很好的保护父类的方法

class Fruit {
    private $color; 

    public function eat() {
        //chew
    } 

    public function setColor($c) {
        $this->color = $c;
    }
} 

class Apple extends Fruit {
    public function eat() {
        //chew until core
    }
} 

class Orange extends Fruit {
    public function eat() {
        //peel
        //chew
    }
} 

上面定义了一个`水果父类` ,同时定义了两个子类`Apple`,`Orange`,此时

$apple = new Apple();
$apple->eat();     //实例化Apple类,调用eat方法,这没毛病

$fruit = new Fruit();
$fruit->eat();     //如果实例化Friut类,调用eat方法就有点奇怪了,What does that taste like???

抽象方法完美的解决了这个问题

abstract class Fruit {
    private $color; 

    abstract public function eat(); 

    public function setColor($c) {
        $this->color = $c;
    }
} 

因此,如果我们需要一个类的子类都实现同一个方法,每个方法的实现方法都不同,此时可以使用抽象方法

接口

使用接口(interface),可以指定某个类必须实现哪些方法,但不需要定义这些方法的具体内容。

  • 接口中只能定义方法名(含参数),不能有方法体
  • 接口中定义的所有方法都必须是公有 (public)
  • 要实现一个接口,使用 implements 操作符,类中必须实现接口中定义的所有方法
  • 设计接口时如果不确定方法参数个数,可以使用 ...$argumens 可变参数代替,或者直接为空,子类中通过传入可变参数或者通过 func_get_args 获取
  • 一个类可以同时实现多个接口,实现多个接口时,接口中的方法不能有重名
  • 接口也可以继承,通过使用 extends 操作符
  • 接口中也可以定义常量

通过接口我们可以很好的降低代码的耦合性

例如:

我有一个数据库,我想写一个类去访问我的数据库,所以我定义了一个接口

interface Database {
function listOrders():array;    //要求次方法返回的数组
function addOrder(array $arr);      //要求次方法参数类型为数组
function removeOrder();
...
}

现在我们使用MYSQL数据库,所以我写了一个mysql的类

class MySqlDatabase implements Database {
function listOrders() :array{...
}

过了一段时间,我们又想改成Oracle数据库,我们又写了一个oracle数据库类去实现接口

class OracleDatabase implements Database {
public function listOrders() :array{...
}

因为我们使用了接口,所有的方法(参数、返回值)都一致,我们只需要修改一行代码即可完成切换

$database = new OracleDatabase();

Trait

从PHP的5.4.0版本开始,PHP提供了一种全新的代码复用的概念,那就是Trait。Trait其字面意思是”特性”、”特点”,我们可以理解为,使用Trait关键字,可以为PHP中的类添加新的特性。

熟悉面向对象的都知道,软件开发中常用的代码复用有继承和多态两种方式。在PHP中,只能实现单继承。而Trait则避免了这点。下面通过简单的额例子来进行对比说明。

trait ezcReflectionReturnInfo {
    function getReturnType() { /*1*/ }
    function getReturnDescription() { /*2*/ }
}

class ezcReflectionMethod extends ReflectionMethod {
    use ezcReflectionReturnInfo;
    /* ... */
}

class ezcReflectionFunction extends ReflectionFunction {
    use ezcReflectionReturnInfo;
    /* ... */
}

声明一个trait 直接使用 trait 关键字 + 类名即可 , 与声明一个类相似

使用trait 使用关键字 use + 类名

注意:从基类继承的成员会被 trait 插入的成员所覆盖。优先顺序是来自当前类的成员覆盖了 trait 的方法,而 trait 则覆盖了被继承的方法。

原文地址:https://www.cnblogs.com/xiaoliwang/p/8997914.html

时间: 2024-08-03 12:55:18

PHP 进阶之 抽象类(abstract)、接口(interface)、Trait(特征)的相关文章

Java基础-抽象类和接口

抽象类与接口是Java语言中对抽象概念进行定义的两种机制,正是由于他们的存在才赋予java强大的面向对象的能力.他们两者之间对抽象概念的支持有很大的相似,甚至可以互换,但是也有区别. 抽象定义: 抽象就是从多个事物中将共性的,本质的内容抽取出来.     例如:狼和狗共性都是犬科,犬科就是抽象出来的概念. 抽象类: Java中可以定义没有方法体的方法,该方法的具体实现由子类完 成,该方法称为抽象方法,包含抽象方法的类就是抽象类. 抽象方法的由来: 多个对象都具备相同的功能,但是功能具体内容有所不

关于类、抽象类和接口的继承关系

关于类.抽象类和接口的继承关系 一.类和抽象类 当实体类Impl继承一个抽象类Abstract,该实体类Impl可以不用实现抽象类Abstract中的所有方法,但是必须实现抽象类中的所有抽象方法. 二.类和接口 当实体类Impl直接实现接口Interface,那么该实体类Impl必须是想接口Interface里面的所有接口方法. 三.抽象类和接口 当抽象类Abstract实现接口Interface,抽象类可以实现接口中的部分接口方法,也可以完全不实现任何接口方法. 理解:因为抽象类的功能类似接口

Java基础学习191221(可变参数,数组,Array类,稀疏数组,继承重写多态,抽象类,接口)

Java基础学习 可变参数 在方法声明中,在指定参数类型后加一个省略号(...). 一个方法中只能指定一个可变参数,它必须是方法的最后一个参数.任何普通参数都必须在它之前声明. public class printMax { public static void main(String[] args) { printMax(1,5,8,78,415,15); } public static void printMax( double... numbers){ if (numbers.length

JAVA之旅(七)——final关键字 , 抽象类abstract,模板方法模式,接口interface,implements,特点,扩展

JAVA之旅(七)--final关键字 , 抽象类abstract,模板方法模式,接口interface,implements,特点,扩展 OK,我们继续学习JAVA,美滋滋的 一.final 我们来聊聊final这个关键字 final可以修饰类,方法和变量 final修饰的类不可以被继承 final修饰的方法不可以被覆盖 final修饰的变量是一个常量,只能被赋值一次 内部类只能访问被final修饰的局部变量 final,故名思意,就是最终的意思,由以上的五种特性,不过final的出现,也是有

【温故知新】c#抽象类abstract与接口interface

1.什么是抽象类 先来看MSDN对抽象类描述: 抽象类是一些留有部分或全部成员未实现的类,以便可以由派生类来提供实现. 在面向对象的编程中,抽象类用作层次结构的基类,并表示不同对象类型组的通用功能. 正如名称“抽象”所暗指的,抽象类通常不会直接与问题域中的具体实体对应. 不过,抽象类会表示多个不同的具体实体之间的共同之处. 仅当存在已声明但未定义的抽象方法时,才会将类视为抽象类. 因此,具有抽象方法的类并不一定是抽象类. 除非类具有未定义的抽象方法,否则不要使用 AbstractClass 特性

接口Interface和抽象类abstract class的区别

abstract class和interface是Java语言中对于抽象类定义进行支持的两种机制,正是由于这两种机制的存在,才赋予了Java强大的面向对象能力. abstract class和interface之间在对于抽象类定义的支持方面具有很大的相似性,甚至可以相互替换,因此很多开发者在进行抽象类定义时对于 abstract class和interface的选择显得比较随意. 其实,两者之间还是有很大的区别的,对于它们的选择甚至反映出对于问题领域本质的理解.对于设计意图的理解是否正确.合理.

C++虚函数virtual,纯虚函数pure virtual和Java抽象函数abstract,接口interface与抽象类abstract class的比较

由于C++和Java都是面向对象的编程语言,它们的多态性就分别靠虚函数和抽象函数来实现. C++的虚函数可以在子类中重写,调用是根据实际的对象来判别的,而不是通过指针类型(普通函数的调用是根据当前指针类型来判断的).纯虚函数是一种在父函数中只定义而不实现的一种函数,不能用来声明对象,也可以被称为抽象类.纯虚函数的实现也可以在类声明外进行定义.C++中的抽象类abstract class是指至少有一个纯虚函数的类,如果一个类全部由纯虚函数组成,不包括任何的实现,被称为纯虚类. Java中的普通函数

Java简明教程 09. 抽象类(abstract class)和接口(interface)

抽象类(abstract class) 描述抽象的事物,  比如人类(human), 就是一个抽象类. 对于人类这个抽象类, 具体的就是某一个人, 比如张三(男)啊, 小红(女)啊,虽然说人都会eat, 可是男人和女人的eat似乎又是不一样的.男人一般都是大口大口的吃, 而女人比较慢条斯理. AbstractDemo.java 1 abstract class Human { //抽象类, 特点: 1. 前面有abstract修饰 2 // 2. 无法直接生成一个对象,需要子类去继承这个类, 并

c#中抽象类(abstract)和接口(interface)的相同点与区别

相同点: 1.都可以被继承 2.都不能被实例化 3.都可以包含方法声明 4.派生类必须实现未实现的方法 区别: 1.抽象基类可以定义字段.属性.方法实现.接口只能定义属性.索引器.事件.和方法声明,不能包含字段. 2.抽象类是一个不完整的类,需要进一步细化,而接口是一个行为规范.微软的自定义接口总是后带able字段,证明其是表述一类“我能做...” 3.接口可以被多重实现,抽象类只能被单一继承 4.抽象类更多的是定义在一系列紧密相关的类间,而接口大多数是关系疏松但都实现某一功能的类中 5.抽象类