zoukankan      html  css  js  c++  java
  • 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中文网

  • 相关阅读:
    【LeetCode OJ】Remove Element
    【LeetCode OJ】Remove Duplicates from Sorted Array
    【LeetCode OJ】Swap Nodes in Pairs
    【LeetCode OJ】Merge Two Sorted Lists
    【LeetCode OJ】Remove Nth Node From End of List
    【LeetCode OJ】Two Sum
    【LeetCode OJ】Majority Element
    最长公共子序列问题
    php fopen与file_get_contents的区别
    PHP 技巧集合
  • 原文地址:https://www.cnblogs.com/xionghao/p/12077619.html
Copyright © 2011-2022 走看看