怎么理解PHP7.2忽略父类方法以及Liskov替换原则相关问题

技术怎么理解PHP7.2忽略父类方法以及Liskov替换原则相关问题这篇文章主要介绍“怎么理解PHP7.2忽略父类方法以及Liskov替换原则相关问题”,在日常操作中,相信很多人在怎么理解PHP7.2忽略父类方法以及Li

本文主要介绍“如何理解PHP7.2的父方法以及Liskov替换原理的相关问题”。在日常操作中,相信很多人对于如何理解PHP7.2的父方法以及Liskov替换原理的相关问题都有疑问。边肖查阅了各种资料,整理出简单易用的操作方法,希望能帮助大家解答“如何理解PHP7.2的母法以及Liskov替换原理的相关问题”的疑惑!接下来,请和边肖一起学习!

细说 PHP 7.2 子类覆盖方法省略参数类型功能以及 Liskov 替换原则

PHP 7.2已经问世一段时间了。只要你关心PHP的发展,你应该已经阅读了所有关于新版本的新改进。这只是一个可能被误解的新功能。

当子类覆盖父方法时,PHP 7.2可以忽略父方法的已定义参数的类型提示:

classFoo

{

public functionbar(someCLaSS $ obj){ }

}

classFoobarextendsFoo

{

Publicfunctionbar($obj){}//这是PHP7.2之前的错误。

}在看一些介绍这个功能的网站时,我说它的目的是“方便重新配置”。如果将来父方法的参数类型改变了,子类就不必再全部改变了”。听起来很合理。根据这种说法,它意味着如果子类忽略了父方法的参数类型,那么当调用它时,它仍然会检查参数类型。实际情况是否是这样,通过做一个实验就知道了:

?服务器端编程语言(Professional Hypertext Preprocessor的缩写)

classFoo

{

}

分类栏

{

publicfunctionsetFoo(Foo$foo)

{

}

}

classBarKidextendsBar

{

publicfunctionsetFoo($foo)

{

}

}

$ kid=newBarKid

$ kid-SetFoo(' Iamstring!');如果上面的语句是正确的,那么在接受字符串参数时,setFoo应该会报告一个错误。但是,上面的代码在7.2下没有任何错误信息,但是如果将参数类型添加到子类的setFoo方法中,它会立即报告错误。记得网上很多说法都不可信,除了我的小站.

上述实验表明子类方法可以省略参数类型,其目的当然不是为了方便重构。真正的目的是什么?

PHP 7.1中新增了一个函数,就是「可以设置方法或函数的参数和返回类型是否可以为空」。有一个规则看起来比较尴尬:“子类方法参数类型的范围比较宽松(即如果父类参数不能为null,子类参数可以支持null),但是返回类型比较紧(如果父类不能返回null,子类一定不能;如果父类可以返回null,子类就不能返回null)”,当时我只是简单的说了一句“娴Liskov替换原则”,但我没有深入介绍。我身边的PHPer不太关注OOP原理,但我觉得应该是每个工程师都知道的,下面就来介绍一下。

Liskov的替换原理很简单:在父类出现的地方,用子类替换也可以运行,即子类可以不假思索地替换父类。其实从语言设计的角度来说,我觉得这个原则是对自然规律的模仿。它不是简单的“模仿”。有兴趣的话可以看看新博客《企鹅不是鸟》。

比如人可以喝酒,可以喝茶,可以喝可乐,可以喝各种饮料,但是作为哺乳动物,人到底能不能喝水呢?另一方面,哺乳动物会喝水,但不一定会喝茶喝可乐,所以人是哺乳动物的一个子类。

从语言设计的角度来看,子类应该是父类的增强版,也就是应该能够处理比父类更多的对象类型,被覆盖的方法参数类型的扩展也体现了这个原则。

让我们谈谈返回类型,它可能有点迂回。子类为什么要缩小返回范围?事实上,很容易想到假设一个方法的返回将被用作另一个方法的参数。比如“水果饮料厂”这一类,有一种“生产”方式,就是把“果汁”退回来,传给“孩子”去“喝”。有一家橙汁厂,属于水果饮料厂的子类。其“制作”方法的返回式比较紧,只能返回“橙汁”,仍然给“孩子”喝,没有任何问题。

再举一个反例。如果有“水果饮料厂”的另一个子类,它的“生产”方法可以返回果酒和果汁,那么这个

子类很显然不能冒着给小朋友喝酒的风险去替换父类。

说完了 Liskov 替换原则,我们再来看看 7.2 里的这个改进,我们这时应该知道其实这也是 Liskov 原则的体现。目前来说,替换原则在 PHP 的实现并不完全。可能有人觉得这个版本是不是也支持『父类没有返回类型,子类可以有返回类型』呢?遗憾的是至少在 7.2 这个版本,并不支持,大家可以自行实验一下。

7.2 的另外一个新功能,是 object 可以作为任何对象的类型。见官方提供例子:

<?php
function test(object $obj) : object
{
    return new SplQueue();
}
test(new StdClass());

其实在 7.2 发布之前,也是出于替换原则,有过一次关于『是否子类可以用 object 类型来替代被覆盖的方法对象参数的类型』,但最终投票并没有通过。虽然我不知道原因,但起码有人提了。

另外目前 PHP 不能像 Java 那样重载(overload),没有办法可以指定覆盖的方法的类型(目前只能把类型直接去掉,有点太粗暴):

<?php
class Foo
{
}
class FooFoo extends Foo
{
}
class Bar
{
    public function foo(FooFoo $foo)
    {
    }
}
class BarBar extends Bar
{
    public function foo(Foo $foo) // 依然会报『子类不兼容父类方法格式』的错误
    {
    }
}

到此,关于“怎么理解PHP7.2忽略父类方法以及Liskov替换原则相关问题”的学习就结束了,希望能够解决大家的疑惑。理论与实践的搭配能更好的帮助大家学习,快去试试吧!若想继续学习更多相关知识,请继续关注网站,小编会继续努力为大家带来更多实用的文章!

内容来源网络,如有侵权,联系删除,本文地址:https://www.230890.com/zhan/96650.html

(0)

相关推荐

  • 美国独享服务器租用特点

    技术美国独享服务器租用特点与廉价的虚拟主机不同,美国独享服务器需要单个网站或网络所有者使用服务器资源。服务器资源(如硬件、软件和操作系统)受到用户的完全控制。此外,物理服务器通常安装在数据中心内。虽然很多用户为了节省成本

    礼包 2021年11月3日
  • 怎么开启Gzip文件做缓存

    技术怎么开启Gzip文件做缓存本篇内容介绍了“怎么开启Gzip文件做缓存”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成! 

    攻略 2021年11月5日
  • Python程序开发问题举例分析

    技术Python程序开发问题举例分析这篇文章主要介绍“Python程序开发问题举例分析”,在日常操作中,相信很多人在Python程序开发问题举例分析问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家

    攻略 2021年12月1日
  • mysql索引最快的方法(mysql索引优化的几种方法)

    技术如何使MySQL的索引更高效这篇文章主要介绍如何使MySQL的索引更高效,文中介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们一定要看完!MySQL中的索引MySQL中的InnoDB引擎使用B+Tree结构来存储

    攻略 2021年12月20日
  • phpmysql数据库可以更新吗(php如何获取mysql更新)

    技术php如何实现mysql更新这篇文章给大家分享的是有关php如何实现mysql更新的内容。小编觉得挺实用的,因此分享给大家做个参考,一起跟随小编过来看看吧。 php实现mysql更新的方法

    攻略 2021年12月15日
  • javaSE中的==和equals的联系与区别是怎样的

    技术javaSE中的==和equals的联系与区别是怎样的这篇文章给大家介绍javaSE中的==和equals的联系与区别是怎样的,内容非常详细,感兴趣的小伙伴们可以参考借鉴,希望对大家能有所帮助。写在前面:==和equ

    攻略 2021年12月2日