zoukankan      html  css  js  c++  java
  • PHP之抽象类与接口

           引入抽象类是PHP 5的一个重要变化。抽象类不能被直接实例化,抽象类中只定义(或部分实现)子类需要的方法。子类可以继承它并通过实现其中的抽象方法,使抽象类具体化。关键字abstract 定义一个抽象类。

          大多数情况下,抽象类至少包含一个抽象方法。抽象方法用abstract关键字声明,其中不能有具体内容。可以像声明普通类方法那样声明抽象方法,但要以分号而不是方法体结束。

     1 <?php
     2 abstract class Simple
     3 {
     4       protected $arr = array(); 
     5 
     6       public function say()
     7       {
     8             echo "hello";
     9       }
    10       
    11       abstract public function write();
    12 }
    13 
    14 class Writer extends simple
    15 {
    16       public function write()
    17      {
    18           // .....具体实现
    19      }
    20 }
    21 ?>

          在PHP 4中,我们可以用包含警告或die()语句模拟抽象类。

    1 <?php
    2 class AbstractClass
    3 {
    4       function abstractFunction()
    5       {
    6            die("AbstractClass::abstractFunction() is abstract\n");
    7       }
    8 }
    9 ?>

         这里存在一个问题,就是这个基类的抽象性只有在抽象方法调用时(即代码运行时)才能检测。在PHP 5中,抽象类在被解析时就被检测,所以更加安全。

    接口

         抽象类提供了具体的实现标准,而接口则是纯粹的模版。接口只能定义功能,而不包括实现的内容。接口可用关键字interface来声明。接口可以包含属性和方法的声明,但是方法体为空。

         定义一个接口:

    1 <?php
    2 interface InterClass
    3 {
    4       public functon example();  
    5 }
    6 ?>

         任何实现接口的类都要实现接口中所定义的所有方法,否则该类必须声明为abstract。一个类可以在声明中使用implements关键字来实现某个接口。

         一个类可以同时继承一个父类和实现任意个接口。extends字句应该放在implements字句之前:

    <?php
    class Consultancy extends TimedService implements Bookable, Chargeable
    {
           //...
    }
    
    ?>

         PHP只支持继承自一个父类,因此extends关键字只能在一个类名之前。

    延迟静态绑定:static 关键字

         学习了抽象类和接口请看下面的代码:

     1 <?php
     2 abstract class DomainObject
     3 {}
     4 
     5 class User extends DomainObject
     6 {
     7        public static function create()
     8        {
     9              return new User();
    10        }
    11 }
    12 
    13 class Document extends DomainObject
    14 {
    15        public static function create()
    16        {
    17              return new Document();
    18        }
    19 }
    20 ?>

          发现在创建这两个类的时候,存在代码重复,如果将重复代码提取到基类呢?

     1  <?php
     2   abstract class DomainObject
     3   {
     4        public static function create()
     5        {
     6            return new self();
     7        }
     8   }
     9  
    10   class User extends DomainObject
    11  {
    12  }
    13  
    14  class Document extends DomainObject
    15  {
    16  }
    17 
    18   Document :: create();
    19 ?>

           可以运行下结果,报错了。。。

           实际上,self对该类所起的作用与$this对对象所起的作用并不完全相同。self指的不是调用的上下文,它指的是解析上下文,因此,如果运行则报错。

           在PHP 5.3中引入了延迟静态绑定的概念。该特性最明显的标志就是新关键字static。static类似于self,但它指的是表调用的类而不是包含类。

     1 <?php
     2    abstract class DomainObject
     3    {
     4         public static function create()
     5         {
     6             return new  static();
     7         }
     8    }
     9   
    10    class User extends DomainObject
    11   {
    12   }
    13   
    14   class Document extends DomainObject
    15   {
    16   }
    17  
    18    var_dump(Document :: create());
    19  ?>

           现在运行则通过。static不仅可以用于实例化。和self和parent一样,static还可以作为静态方法调用的标示符,甚至从非静态上下文中调用。

     1 <?php
     2 abstract class DomainObject
     3 {
     4     private $group;
     5 
     6     public function __construct()
     7     {
     8         $this->group = static::getGroup();
     9     }
    10 
    11     public static function create()
    12     {
    13         return new static();
    14     }
    15 
    16     static function getGroup()
    17     {
    18         return 'Default';
    19     }
    20 }
    21 
    22 class User extends DomainObject
    23 {
    24 }
    25 
    26 class Document extends DomainObject
    27 {
    28     static function getGroup()
    29     {
    30         return "document";
    31     }
    32 }
    33 
    34 class SpreadSheet extends Document
    35 {
    36 }
    37 
    38 print_r(User::create());
    39 print_r(SpreadSheet::create());
    40  ?>

           运行看结果,PHP5.3之前self只能查找DomainObject类中的getGroup()。

    <<因果&矛盾>>
  • 相关阅读:
    第十七节:织梦做自定义表单在线预约的方法
    ExecuteNonQuery()返回值
    WCF服务编程读书笔记(6):错误
    ubuntu 工作区切换快捷键设置
    a pubhub service
    淘宝提供了Rubygems的国内镜像站点 ruby rails源
    新rails安装过程记录
    XMLRPC HOWTO
    XMLRPC HOWTO
    metaweblog api相关
  • 原文地址:https://www.cnblogs.com/bridger/p/2715055.html
Copyright © 2011-2022 走看看