php抽象类abstract与接口理解与示…

2023-05-16

PHP抽象类abstract的理解对于初学者来说不是非常熟悉,我们还需要在不断的代码积累中来积累这方面的知识。其实抽象类和接口类有一部分很像。

 

记得在哪里看见这样一句话,抽象类就把类像的部分抽出来,这句看上去很搞笑,其实它说出了抽象类的真理,抽象类的作用是,当你发现你的很多类里面用很多方法你不断的在重复写,那你就可以考虑使用抽象类了,你可能会说“我不是可以重写一个类每个公共类我个实例化一个这个公共类,调用相同的方法就可以了”,这里是可以,实际上抽象类做的工作也就是这个,不过他省去了你实例化的这个步骤,让你就像直接调用PHP抽象类abstract方法一样方便,而且你还可以重载这个方法。如:


  
  1. abstract class BaseShop  
  2. {  
  3. public function buy($gid)  
  4. {  
  5. echo('你购买了ID为 :'.$gid.'的商品');  
  6. }  
  7. public function sell($gid)  
  8. {  
  9. echo('你卖了ID为 :'.$gid.'的商品');  
  10. }  
  11. public function view($gid)  
  12. {  
  13. echo('你查看了ID为 :'.$gid.'的商品');  
  14. }  
  15. }  
  16. class BallShop extends BaseShop  
  17. {  
  18. var $itme_id null;  
  19. public function __construct()  
  20. {  
  21. $this->itme_id 2314;  
  22. }  
  23. public function open()  
  24. {  
  25. $this->sell($this->itme_id);  
  26. }  

这里是一个例子,想上面一样我定义了一个商店类,抽出了它所有像的部分,买(buy),卖(sell),看(view),并且抽象类里都实现了这些方法,那么继承它的子类就自动获得了这些方法,子类就做它自己独特的东西,介绍代码的重复,提高复用性。

结论: PHP抽象类abstract就是一个类的服务提供商,拥有众多服务,你不用必须用,当需要的时候你来用就可以,如果你觉得不提供服务不满意,你还可以自己来做。

 

加深理解与运用

一、 抽象类abstract class

1 .抽象类是指在 class 前加了 abstract 关键字且存在抽象方法(在类方法 function 关键字前加了 abstract 关键字)的类。

2 .抽象类不能被直接实例化。抽象类中只定义(或部分实现)子类需要的方法。子类可以通过继承抽象类并通过实现抽象类中的所有抽象方法,使抽象类具体化。

3 .如果子类需要实例化,前提是它实现了抽象类中的所有抽象方法。如果子类没有全部实现抽象类中的所有抽象方法,那么该子类也是一个抽象类,必须在 class 前面加上 abstract 关键字,并且不能被实例化。

    代码如下:

abstract class A 

         
        protected $value1 = 0; 
        private $value2 = 1; 
        public $value3 = 2; 
         
        public function my_print() 
       
                echo "hello,world/n"; 
       
         
        abstract protected function abstract_func1(); 
        abstract protected function abstract_func2(); 

abstract class B extends A 

        public function abstract_func1() 
       
              echo "implement the abstract_func1 in class A/n"; 
       
         
        //abstract protected function abstract_func2(); 

class C extends B 

        public function abstract_func2() 
       
              echo "implement the abstract_func2 in class A/n"; 
       

4 .如果像下面这样创建了一个继承自 A 的子类 B ,但是不实现抽象方法 abstract_func() :

    代码如下:

Class B extends A{};

 那么程序将出现以下错误:

 

  代码如下:

  Fatal error: Class B contains 1 abstract method and must therefore be declared abstract or implement the remaining methods (A::abstract_func)
 

 5 .如果 B 实现了抽象方法 abstract_func() ,那么 B 中 abstract_func() 方法的访问控制不能比 A 中 abstract_func() 的访问控制更严格,也就是说:

(1)      如果 A 中 abstract_func() 声明为 public ,那么 B 中 abstract_func() 的声明只能是 public ,不能是 protected 或 private

(2)      如果 A 中 abstract_func() 声明为 protected ,那么 B 中 abstract_func() 的声明可以是 public 或 protected ,但不能是 private

(3)      如果 A 中 abstract_func() 声明为 private ,嘿嘿,不能定义为 private 哦!( Fatal error : Abstract function A::abstract_func() cannot be declared private )

二、 接口interface

1 .抽象类提供了具体实现的标准,而接口则是纯粹的模版。接口只定义功能,而不包含实现的内容。接口用关键字 interface 来声明。

2 . interface 是完全抽象的,只能声明方法,而且只能声明 public 的方法,不能声明 private 及 protected 的方法,不能定义方法体,也不能声明实例变量 。然而, interface 却可以声明常量变量 。但将常量变量放在 interface 中违背了其作为接口的作用而存在的宗旨,也混淆了 interface 与类的不同价值。如果的确需要,可以将其放在相应的 abstract class 或 Class 中。

    代码如下:

interface iA 

        const AVAR=3; 
        public function iAfunc1(); 
        public function iAfunc2(); 

echo iA:: AVAR;

3 .任何实现接口的类都要实现接口中所定义的所有方法

    代码如下:

class E implements iA 

        public function iAfunc1(){echo "in iAfunc1";} 
        public function iAfunc2(){echo "in iAfunc2";} 

否则该类必须声明为 abstract 。

    代码如下:

abstract class E implements iA{} 

4 .一个类可以在声明中使用 implements 关键字来实现某个接口。这么做之后,实现接口的具体过程和继承一个仅包含抽象方法的抽象类是一样的。一个类可以同时继承一个父类和实现任意多个接口。 extends 子句应该在 implements 子句之前。 PHP 只支持继承自一个父类,因此 extends 关键字后只能跟一个类名。

  代码如下:

interface iB 

        public function iBfunc1(); 
        public function iBfunc2(); 

class D extends A implements iA,iB 

        public function abstract_func1() 
       
              echo "implement the abstract_func1 in class A/n"; 
       
        public function abstract_func2() 
       
              echo "implement the abstract_func2 in class A/n"; 
       
        public function iAfunc1(){echo "in iAfunc1";} 
        public function iAfunc2(){echo "in iAfunc2";} 
        public function iBfunc1(){echo "in iBfunc1";} 
        public function iBfunc2(){echo "in iBfunc2";} 


class D extends B implements iA,iB 

        public function abstract_func1() 
       
              parent::abstract_func1(); 
              echo "override the abstract_func1 in class A/n"; 
       
        public function abstract_func2() 
       
              echo "implement the abstract_func2 in class A/n"; 
       
        public function iAfunc1(){echo "in iAfunc1";} 
        public function iAfunc2(){echo "in iAfunc2";} 
        public function iBfunc1(){echo "in iBfunc1";} 
        public function iBfunc2(){echo "in iBfunc2";} 

5 .接口不可以实现另一个接口,但可以继承多个

  代码如下:

interface iC extends iA,iB{} 
class F implements iC 

        public function iAfunc1(){echo "in iAfunc1";} 
        public function iAfunc2(){echo "in iAfunc2";} 
        public function iBfunc1(){echo "in iBfunc1";} 
        public function iBfunc2(){echo "in iBfunc2";} 

三、 抽象类和接口的异同

1. 相同点:

(1)      两者都是抽象类,都不能实例化。

(2)      interface 实现类及 abstract class 的子类都必须要实现已经声明的抽象方法。

2. 不同点:

(1)      interface 需要实现,要用 implements ,而 abstract class 需要继承,要用 extends 。

(2)      一个类可以实现多个 interface ,但一个类只能继承一个 abstract class 。

(3)      interface 强调特定功能的实现,而 abstract class 强调所属关系。

(4)      尽管 interface 实现类及 abstract class 的子类都必须要实现相应的抽象方法,但实现的形式不同。 interface 中的每一个方法都是抽象方法,都只是声明的 (declaration, 没有方法体 ) ,实现类必须要实现。而 abstract class 的子类可以有选择地实现。这个选择有两点含义: a) abstract class 中并非所有的方法都是抽象的,只有那些冠有 abstract 的方法才是抽象的,子类必须实现。那些没有 abstract 的方法,在 abstract class 中必须定义方法体; b) abstract class 的子类在继承它时,对非抽象方法既可以直接继承,也可以覆盖;而对抽象方法,可以选择实现,也可以留给其子类来实现,但此类必须也声明为抽象类。既是抽象类,当然也不能实例化。

(5)      abstract class 是 interface 与 class 的中介。 abstract class 在 interface 及 class 中起到了承上启下的作用。一方面, abstract class 是抽象的,可以声明抽象方法,以规范子类必须实现的功能;另一方面,它又可以定义缺省的方法体,供子类直接使用或覆盖。另外,它还可以定义自己的实例变量,以供子类通过继承来使用。

(6)      接口中的抽象方法前不用也不能加 abstract 关键字,默认隐式就是抽象方法,也不能加 final 关键字来防止抽象方法的继承。而抽象类中抽象方法前则必须加上 abstract 表示显示声明为抽象方法。

(7)      接口中的抽象方法默认是 public 的,也只能是 public 的,不能用 private , protected 修饰符修饰。而抽象类中的抽象方法则可以用 public , protected 来修饰,但不能用 private 。

3. interface 的应用场合

(1)      类与类之间需要特定的接口进行协调,而不在乎其如何实现。

(2)      作为能够实现特定功能的标识存在,也可以是什么接口方法都没有的纯粹标识。

(3)      需要将一组类视为单一的类,而调用者只通过接口来与这组类发生联系。

(4)      需要实现特定的多项功能,而这些功能之间可能完全没有任何联系。

4. abstract class 的应用场合

一句话,在既需要统一的接口,又需要实例变量或缺省的方法的情况下,就可以使用它。最常见的有:

(1)      定义了一组接口,但又不想强迫每个实现类都必须实现所有的接口。可以用 abstract class 定义一组方法体,甚至可以是空方法体,然后由子类选择自己所感兴趣的方法来覆盖。

(2)      某些场合下,只靠纯粹的接口不能满足类与类之间的协调,还必需类中表示状态的变量来区别不同的关系。 abstract 的中介作用可以很好地满足这一点。

(3)      规范了一组相互协调的方法,其中一些方法是共同的,与状态无关的,可以共享的,无需子类分别实现;而另一些方法却需要各个子类根据自己特定的状态来实现特 定的功能 。

 

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

php抽象类abstract与接口理解与示… 的相关文章

  • 使用 PHP 中的 GD 库在图像上绘图

    我创建了一个代码来生成随机图案图像 它创建一个具有给定宽度和高度的图像 并用 40x40 像素的小矩形填充它 这是我的代码
  • if/else 简写来定义变量

    我很难理解 if else 的 php 简写是如何描述的here https stackoverflow com questions 20233207 php if shorthand and echo in one line possib
  • 使用 ImageMagick (PHP) 将 2 个图像并排合并为 1 个图像

    我认为这是一件容易的事 我有 2 张图片 JPG 我希望它们合并成一张图片 其中 2 张图片并排 所以我有图片 A 和图片 B 我想要图片 AB 并排 两个图像具有相同的宽度和高度 在本例中 宽度 200px 高度 300px 但是第二个图
  • 选择一组数字以达到最小总数的算法

    给定 一组数字n 1 n 2 n 3 n x 还有一个数字M 我想找到最好的组合 n a n b n c n gt M 该组合应达到达到或超过 M 所需的最小值 没有其他组合可以提供更好的结果 将在 PHP 中执行此操作 因此可以使用 PH
  • 如何让Apache服务index.php而不是index.html?

    如果我将以下行放入index html文件 使 Apache 包含index php file 参观index html页面向我显示了这个 这是为什么 为什么它实际上不包含 PHP 文件 正如其他人指出的那样 您很可能没有 html设置为处
  • get url 重定向时 File_get_contents() 不起作用

    我正在使用的功能是 function http post url data data url http build query data data len strlen data url date default timezone set
  • 媒体的 Google Cloud Storage 签名网址

    我已经建立了一个视频网站 为用户提供 m3u8 和关联的 ts 文件 我不希望媒体文件免费可用 所以我所做的是 当用户在网站上时 在 mysql 中使用他们的 IP 和令牌创建一个会话 当他们请求特定媒体子域 mp4 domain com
  • CodeIgniter 控制器 - JSON - AJAX

    我正在尝试通过 AJAX 使用 CodeIgniter 发送表单构建 并尝试使用 JSON 获取响应 但是 我只在打开开发人员选项卡时看到响应 我什至不确定这是否实际上是响应 因为它显示了两个 json 数据 它所显示的只是加载旋转器 然后
  • 访问sendBeacon发送的数据

    文档表明sendBeacon通过发送其数据HTTP POST request 但在 PHP 中 POST变量似乎是一个空数组 这是我的 JavaScript 代码 navigator sendBeacon beacon log php My
  • 如何纠正这个非法字符串偏移?

    我收到此错误 警告 第 32 行 home mysite public html wp content themes evento lib php extra class php 中的非法字符串偏移 type 我意识到文件中的这部分代码是错
  • 在 WooCommerce 中添加到购物车之前清空购物车

    我正在使用 WP 作业管理器和 Woo Subscriptions Now 最初 我选择了一个套餐 Woo Subscription 然后我添加了所有细节 但没有提交 回到网站 所以要再次购买 我需要选择一个套餐 于是我选择了套餐并填写了详
  • 在 Yii 的标准中如何获得计数 (*)

    我正在尝试构建一个具有以下内容的查询group by属性 我正在尝试得到id和count它一直告诉我count is invalid列名 我怎样才能得到count来自group by询问 工作有别名 伊伊 1 1 11 其他不及格 crit
  • Facebook PHP SDK - 如何获取访问令牌?

    我正在尝试从我的应用程序在用户的 Facebook 墙上发帖 用户授予应用程序在他的墙上发布的权限 并且我在数据库中有用户ID 我需要自动发送帖子 而无需用户再次登录 我的代码是 try require once dirname FILE
  • 如何将 Smarty 3 包含到 Laravel 4 中?

    我是 Laravel 的新手 所以仍在习惯这些概念 但是我有大约 10 年的使用 Smarty 的经验 所以我希望利用这一点 除了事实上 Blade 似乎缺乏太多我发现有用且在 Smarty 中开箱即用的功能 但无论如何除了这个问题的要点之
  • 如何通过ssh检查ubuntu服务器上是否存在php和apache

    如何通过ssh检查Ubuntu服务器上apache是 否安装了php和mysql 另外如果安装的话在哪个目录 如果安装了其他软件包 例如 lighttpd 那么它在哪里 确定程序是否已安装的另一种方法是使用which命令 它将显示您正在搜索
  • 如何从 Laravel 执行存储过程

    我需要在表单提交数据后执行存储过程 我让存储过程按照我想要的方式工作 并且我的表单正常工作 我只是不知道从 laravel 5 执行 sp 的语句 它应该是这样的 执行 my stored procedure 但我似乎在网上找不到类似的东西
  • Stream_context_set_params 不适用于 ssh2.sftp 包装器

    我想使用类似的功能here http www php net manual en function stream notification callback php 请检查以下代码 function notify notification
  • ZF3/2 - 如何捕获 EVENT_DISPATCH 侦听器中引发的异常?

    有什么方法可以在 EVENT DISPATCH 监听器中抛出异常吗 class Module public function onBootstrap EventInterface event application event gt get
  • 如何使用 php 将 *.xlsb 转换为数组或 *.csv

    我正在尝试转换 xlsb文件到php array or csv文件 或至少 xls 我尝试使用PHPExcel 但看起来它无法识别该文件中的内容 我注意到 你可以重命名 xlsb文件到 zip文件 然后使用命令行解压缩unzip zip 之
  • 使用 crypt() 加密

    我目前正在做一个非常安全的登录系统 但我是 crypt 函数的新手 需要一些快速帮助 我在注册过程中使用 crypt 加密密码字符串并将其保存到数据库中 但是 我如何在登录过程中解密密钥 或者我应该怎么做 或者是否可以对提交的密码字符串进行

随机推荐

  • 关于编程语句i++与++i的区别用法

    首先我们定义一个变量i xff0c int i 61 5 xff1b 然后我们做执行printf xff08 d xff0c i 43 43 xff09 xff1b 我们会发现输出结果是5 是为什么呢 xff0c 我们要搞清楚printf
  • eclipse出现 Some character…

    原文地址 xff1a eclipse出现 Some characters cannot be mapped using 34 GBK 34 character encoding 错误 作者 xff1a 赫西尼 Window gt Profe
  • php实现二维数组转置

    arr 61 array array 1 2 3 array 4 5 6 for i 61 0 i for j 61 0 j arr1 j i 61 arr i j for k 61 0 k for l 61 0 l echo arr1 k
  • PX4在GAZEBO仿真中加载iris模型问题

    目录 1 PX4启动仿真的launch系列文件1 1 单个launch文件解读1 2 对iris模型添加相机1 3 bashrc环境变量问题 2 一些Bug2 1 我的台式机无法加载模型2 1 1 若使用 96 v1 9 2版本 96 2
  • Springboot应用中设置Cookie的SameSite属性

    转载自https springboot io t topic 2602 一 Cookie除了key和value以外有几个属性 httpOnly 是否允许js读取cookiesecure 是否仅仅在https的链接下 xff0c 才提交coo
  • TCP如何保证可靠性,TCP如何实现可靠性传输的

    tcp 如何保证可靠性 大家都知道TCP是可靠性传输协议 xff0c 既然是可靠的 xff0c 就需要解决比如包丢失了 数据被破坏了 包重复了 乱序了等等这样的问题 下面将从几个方面介绍TCP的可靠性 1 校验和 TCP每一段报文都有校验和
  • php中标准使用类的方法

  • php复选框中获取文本框、密码域、…

    复选框能够进行项目的多项选择 xff0c 浏览者在填写一些表单时 xff0c 有时需要选择多个项目 xff08 如 xff1a 兴趣爱好等 xff09 复选框一般是多个同时存在 xff0c 为了便于传值 xff0c name的名字可以定义为
  • php页面js隐藏域的运用

    好聪明 四则运算 计算矩形 请输入第二个数 请选择运算符 43 请输入长请输入宽 请输入第一个数 好聪明 四则运算 计算矩形 请输入第一个数请输入第二个数请选择运算符 43 点击按钮 xff0c 可切换不同页面
  • mysql 空值,null与not null

    可以的 原文地址 xff1a mysql 空值 xff0c null与not null 作者 xff1a 五月jks gyS mysql探究之null与not null 1 我字段类型是not null xff0c 为什么我可以插入空值 2
  • 解决Missing argument 1 for…

    原文地址 xff1a 解决Missing argument 1 for DataTest testAdd 作者 xff1a 晨风 在使用PHPUnit的DataProvider方法时 xff0c 按官方帮助文档所说编写测试脚本如下 xff1
  • 色彩 标准卡大全及配色方案

    原文地址 xff1a 色彩 标准卡大全及配色方案 作者 xff1a 刘义0 配色方案浅析 一 红色的色感温暖 xff0c 性格刚烈而外向 xff0c 是一种对人刺激性很强的色 红色容易引起人的注意 xff0c 也容易使人兴奋 激动 紧张 冲
  • php中define()函数和defined…

    原文地址 xff1a php中define 函数和defined 函数的使用 及来防止恶意调用 作者 xff1a 疯子的博客 php中define 函数和defined 函数的使用 define 用来定义常量 xff0c 常量也是全局范围的
  • __FILE__    __LINE__

    我们在写程序的时候 xff0c 总是或多或少会加入一些printf之类的语句用于输出调试信息 xff0c 但是printf语句有个很不方便的地方就是当我们需要发布程序的时候要一条一条的把这些语句删除 xff0c 而一旦需要再次调试的时候 x
  • php魔术引用

    魔术引用发生作用是在传递 GET POST COOKIE时 下面是案例 代码 1 条件 xff1a magic quotes gpc 61 off 写入数据库的字符串未经过任何过滤处理 从数据库读出的字符串也未作任何处理 数据 xff1a
  • php类中private public prot…

    原文地址 xff1a php类中private public protected 三者之间的关系 作者 xff1a 任鹏飞 public 表示全局 xff0c 类内部外部子类都可以访问 xff1b private表示私有的 xff0c 只有
  • Python和C++版本的ROS自定义消息调试

    对python和C 43 43 版本的ROS自定义消息调试 xff08 包含自己编写的父消息嵌套子消息的例子 传送门gitee链接 xff09 文章目录 对python和C 43 43 版本的ROS自定义消息调试Step1 xff1a 工程
  • php中类的全面讲解

    一 xff1a 结构和调用 实例化 xff1a class className xff0c 调用 xff1a obj 61 new className 当类有构造函数时 xff0c 还应传入参数 如 obj 61 new className
  • socket通信简介

    我们深谙信息交流的价值 xff0c 那网络中进程之间如何通信 xff0c 如我们每天打开浏览器浏览网页时 xff0c 浏览器的进程怎么与web服务器通信的 xff1f 当你用QQ聊天时 xff0c QQ进程怎么与服务器或你好友所在的QQ进程
  • php抽象类abstract与接口理解与示…

    PHP抽象类abstract的理解对于初学者来说不是非常熟悉 xff0c 我们还需要在不断的代码积累中来积累这方面的知识 其实抽象类和接口类有一部分很像 记得在哪里看见这样一句话 xff0c 抽象类就把类像的部分抽出来 xff0c 这句看上