怎么理解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)

相关推荐

  • 如何在Cubieboard上搭建个人云存储

    技术怎么在Cubieboard上搭建个人云存储这篇文章将为大家详细讲解有关怎么在Cubieboard上搭建个人云存储,文章内容质量较高,因此小编分享给大家做个参考,希望大家阅读完这篇文章后对相关知识有一定的了解。准备工作

    攻略 2021年12月13日
  • 解析JVM内存监控流程的示例分析

    技术解析JVM内存监控流程的示例分析解析JVM内存监控流程的示例分析,很多新手对此不是很清楚,为了帮助大家解决这个难题,下面小编将为大家详细讲解,有这方面需求的人可以来学习下,希望你能有所收获。你对JVM内存监控是否熟悉

    攻略 2021年10月23日
  • 手写Compose方法的有哪些

    技术手写Compose方法的有哪些本篇内容主要讲解“手写Compose方法的有哪些”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“手写Compose方法的有哪些”吧!前言:为什

    攻略 2021年10月21日
  • 速度单位换算,物理长度、速度单位换算

    技术速度单位换算,物理长度、速度单位换算常用单位常用的长度单位有速度单位换算:公里{千米} (km)、分米(dm)、厘米(cm)、毫米(mm)、微米(μm)、纳米(nm)、皮米(pm)、飞米(fm)。
    (1)公里
    公里又

    生活 2021年10月30日
  • awk常用选项有哪些

    技术awk常用选项有哪些小编给大家分享一下awk常用选项有哪些,相信大部分人都还不怎么了解,因此分享这篇文章给大家参考一下,希望大家阅读完这篇文章后大有收获,下面让我们一起去了解一下吧!1.awk 的语法 awk

    攻略 2021年11月23日
  • react开发app小程序(react开发小程序框架有哪些)

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

    攻略 2021年12月23日