PHP中Abstract与Interface区别

Abstract Class
和C++中的抽象类概念一样,包含有纯虚函数(Java和Php中叫abstract method)的类叫做Abstract Class。
我们有时候也把abstract Class叫做base class,因为base class不能直接生成对象。

代码示例 :

abstract class example
{
   public function xyz()
   {
    return 1;
   }
}
$a = new example();//this will throw error in php

PHP中的abstract class和其他oop语言一样,我们用关键字 abstract 来声明一个抽象类,如果你想直接生成这个类的对象,会报错。
abstract class是用来被继承和被实现的,否则将毫无意义。

代码示例 :

abstract class testParent
{
    public function abc()
    {
        //body of your funciton
    }
}
class testChild extends testParent
{
    public function abc()
    {
        //body of your function
    }
}
$a = new testChild();//abstract class 的继承者并且实例化了    

$a = new testChild();//abstract class 的继承者并且实例化了
testChild通过关键字extends 继承了抽象类 testParent, 然后我们就可以生成 一个testChild的对象了。

PHP中的abstract method的实现

示例代码 :

abstract class abc
{
    abstract protected function f1($a , $b);
}
class xyz extends abc
{
    protected function f1($name , $address)
    {
        echo $name.‘住在‘.$address;
    }
}
$a = new xyz();

在abc中,我们用关键字abstract 声明了一个abstract method f1。
在PHP中一旦你在abstract class中声明了一个abstract method,那么所有继承这个class的子类都必须要去声明这个method,否则,php会报错。

示例代码:

abstract class parentTest
{
    abstract protected function f1();
    abstract public function f2();
    //abstract private function f3(); //this will trhow error
}
class childTest extends parentTest
{
    public function f1()
    {
    //body of your function
    }
    public function f2()
    {
    //body of your function
    }
    protected function f3()
    {
    //body of your function
    }
}
$a = new childTest();

申明一个private的abstract method将会报错,因为private method只能在当前的类中使用。
注意到在abstract class中 f1函数是protected,但是在子类中我们可以将其声明为public的。
没有任何一种可见性比公共可见性受到的限制更少。

###############################################################

Interface
interface将会强迫用户去实现一些method。
例如有一个class中必须要求set ID和Name这两个属性,
那么我们就可以把这个class申明为interface,
这样所有继承自这个class的derived class都将强制必须实现setId和setName两个操作

代码示例:

Interface abc
{
    public function xyz($b);
}

和其他oop语言一样,我们用关键字Interface 来声明。
在这个interface里面我们声明了一个method xyz,则任何时候,子类中都必须申明这样的一个method xyz

示例代码:

class test implements abc
{
    public function xyz($b)
    {
    //your function body
    }
}

你可以用关键字 implements 来继承自interface。
在interface中,只能使用public,而不能使用诸如protected和private

示例代码:

interface template1
{
    public function f1();
}
interface template2 extends template1
{
    public function f2();
}
class abc implements template2
{
    public function f1()
    {
    //Your function body
    }
    public function f2()
    {
    //your function body
    }
}

你可以用extends关键字来继承interface,好像class那样。
这里的template2将包含所有template1的属性,因此在implements自template2的class abc,将必须实现 function f1和f2,
还可以extends 多个 interface

interface template1
{
    public function f1();
}
interface template2
{
    public function f2();
}
interface template3 extends template1, template2
{
    public function f3();
}
class test implements template3
{
    public function f1()
    {
    //your function body
    }
    public function f2()
    {
    //your function body
    }
    public function f3()
    {
    //your function body
    }
}

同时,你的class也可以implements多个interface

但是如果两个interface包含同样名字的method,那么你的class将不能同时implement他们。
继承自interface中的method必须有同样的参数规范,例如下面的代码是可行的

代码示例:

interface template1
{
    public function f1($a)
}
class test implements template1
{
    public function f1($a)
    {
        echo $a;
    }
}
//BUT  下面就会出现错误
interface template1
{
    public function f1($a)
}
class test implements template1
{
    public function f1()
    {
        echo $a;
    }
}    

但是,我们不需要把两个method里面的参数命名为同样的名称,下面的代码是可行的

代码示例:

interface template1
{
    public function f1($a)
}
class test implements template1
{
    public function f1($name)
    {
        echo $name;
    }
}

同时,如果使用默认值,你还可以改变参数的默认值,下面的代码是可行的

示例代码:

interface template1
{
    public function f1($a = 20)
}
class test implements template1
{
    public function f1($name  = ‘xiaoming‘)
    {
        echo $name;
    }
}

总结Abstract Class和Interface之间的不同:

1.在Abstract class中并非所有的method都必须是抽象的,但是在interface中所有的method都自动成为抽象的。就是在子类中必须声明和实现

2.multiple inheritance(多重继承)意思是 在interface中,一个class可以同时implements好多个interface;但是在abstract classes中,只能extends一个class。

3.interface中的method必须是public的,但是在abstract class中可以是public或者protected。

4.在abstract class中你可以同时声明(declare)和定义(define)methodes,但是在interface中你只能定义那个methods

参考来源  php中文网

原文地址:https://www.cnblogs.com/xionghao/p/12077619.html

时间: 2024-08-30 04:33:27

PHP中Abstract与Interface区别的相关文章

java中abstract和interface的區別(轉)

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

Java中abstract与interface

抽象类(abstract class)的特点: 1.抽象类.抽象方法都必须使用abstract修饰. 2.抽象类中,可以有非抽象方法,甚至可以是没有任何方法或变量的空类. 对于抽象类中不定义抽象方法的用意在于:使该类不能被创建对象. 3.抽象方法,是不能有方法体的. 对于抽象方法的访问限制符,可以是public.protected.不写. 4.抽象类,不能使用new创建对象. 5.抽象类的抽象方法,如果只有部分抽象方法被子类重写,则该子类依然是抽象类:如果抽象类的全部抽象方法被子类重写,则该子类

virtual、abstract、interface区别以及用法

virtual 用于在基类中的使用的方法,使用的情况为: 情况1:在基类中定义了virtual方法,但在派生类中没有重写该虚方法.那么在对派生类实例的调用中,该虚方法使用的是基类定义的方法. 情况2:在基类中定义了virtual方法,然后在派生类中使用override重写该方法.那么在对派生类实例的调用中,该虚方法使用的是派生重写的方法. 通俗地讲:老爸用virtual告诉儿子:"孩子,你要工作,找不到事做就跟我一样扫地". 儿子用override告诉全世界:"我要改变家族的

`Java`中`abstract class`与`interface`区别

abstract class Java中允许使用abstract修饰符声明方法,此时只定义方法但是不实现方法(abstract修饰的方法没有主体,只有一个签名和一个分号). 以下是abstract方法和这些方法所在的abstract类相关的规则: 只要类中有一个abstract方法,那么这个类本身就自动成为abstract,而且必须声明为abstract class,否则会导致编译错误; abstract class无法实例化; abstract类的子类必须覆盖超类的每个abstract方法,并

C#中Abstract和Virtual的区别

c# 中 Abstract和Virtual比较容易混淆,都与继承有关,并且涉及override的使用.下面讨论一下二者的区别: 一.Virtual方法(虚方法) virtual 关键字用于在基类中修饰方法.virtual的使用会有两种情况: 情况1:在基类中定义了virtual方法,但在派生类中没有重写该虚方法.那么在对派生类实例的调用中,该虚方法使用的是基类定义的方法. 情况2:在基类中定义了virtual方法,然后在派生类中使用override重写该方法.那么在对派生类实例的调用中,该虚方法

java abstract与interface解析

java abstract与interface解析 abstract 定义 在面向对象的概念中,所有的对象都是通过类来描述.但是,反过来,不是所有的类都是用来描述对象的(把类具体化).如果一个类没有包含足够的信息来描述一个具体的对象,那么这个类就是抽象类. 比如,我们进行一个图形编辑软件的开发,就会发现问题域中存在圆,三角形这样一些具体的概念,它们是不同的,但是它们又都属于形状这样一个概念.形状这个概念在问题域中是不存在的,它就是一个抽象的概念.正是因为抽象的概念在问题领域没有对应的具体概念,所

ios中@class和 #import区别

很多刚开始学习iOS开发的同学可能在看别人的代码的时候会发现有部分#import操作写在m文件中,而h文件仅仅使用@class进行声明,不禁纳闷起来,为什么不直接把#import放到h文件中呢?这 是因为h文件在修改后,所有import该h文件的所有文件必须重 新build,因此,如果把#import写在h文件中,import该h文件的文件也就会产生不必要的编译,增加编译时间,特别是在项目文件多的情况 下.想象一下,如果只是修改一个h文件而导致上百个文件不必要的编译,那是一件多么让人纠结的事情.

JAVA中extends 与implements区别

JAVA中extends 与implements区别 JAVA中extends 与implements有啥区别?1. 在类的声明中,通过关键字extends来创建一个类的子类.一个类通过关键字implements声明自己使用一个或者多个接口.extends 是继承某个类, 继承之后可以使用父类的方法, 也可以重写父类的方法; implements 是实现多个接口, 接口的方法一般为空的, 必须重写才能使用2.extends是继承父类,只要那个类不是声明为final或者那个类定义为abstract

redis中save和bgsave区别

转自:redis中save和bgsave区别 SAVE 和 BGSAVE 两个命令都会调用 rdbSave 函数,但它们调用的方式各有不同: SAVE 直接调用 rdbSave ,阻塞 Redis 主进程,直到保存完成为止.在主进程阻塞期间,服务器不能处理客户端的任何请求. BGSAVE 则 fork 出一个子进程,子进程负责调用 rdbSave ,并在保存完成之后向主进程发送信号,通知保存已完成. Redis 服务器在BGSAVE 执行期间仍然可以继续处理客户端的请求.