- Java 双重比较
- java - 比较器与 Apache BeanComparator
- Objective-C 完成 block 导致额外的方法调用?
- database - RESTful URI 是否应该公开数据库主键?
我以为我了解 LSP,但看来我完全错了。我有以下类(class):
class PrimitiveValue {
}
class StringValue extends PrimitiveValue {
}
class A {
public function foo(StringValue $value) {
}
}
class B extends A {
public function foo(PrimitiveValue $value) {
}
}
注意基类A接受子类 StringValue作为参数类型,子类B接受父类PrimitiveValue。我之所以这样说,是因为到处都会有人问类似的问题,只是类型相反。
根据我的理解,B 类中的方法 foo() 接受父方法接受的任何内容,再加上更多,因为它接受基类型 PrimitiveValue。因此,任何只看到类 A 的调用者都会传递 B 可以处理的值,而不会违反 LSP。知道它是 B 的调用者可以做出更强的假设,并可以自由传递其他 PrimitiveValue 子类型。
然而,当我执行代码时,出现错误:
严格 (2048):B::foo() 的声明应与 A::foo(StringValue $value) 兼容 [APP/Controller/TestLocalController.php,第 17 行]
我哪里错了?我认为最有帮助的是一个示例,说明如何传递违反代码对该值所做假设的值。假设很清楚我要实现的目标,还请添加有关如何正确执行此操作的代码。
最佳答案
What am I getting wrong? I think most helpful would be an example of how a value can be passed that violates the assumptions the code makes about that value.
你没有误解LSP,在子类方法中允许更大的类型并不违反原则;事实上,你所描述的是contravariant method argument types。 ,由于设计或实现困难,PHP 不支持某些内容。
就个人而言,我对这种方法的唯一保留意见是子类中较弱类型的处理被父类(super class)隐藏了。
Assuming that it is clear what I'm trying to achieve, please also add code on how to do it correctly.
PHP 中的方法参数类型是不变的,即每个参数的类型(如果在父级中提供)在覆盖方法时必须完全匹配。虽然此行为已在 past 中讨论过再次长大recently随着return type hinting的介绍,即使在下一个主要版本中也不能保证可用。
为了克服这个问题,您目前被迫让原始类型和派生类型都实现相同的接口(interface),然后在父类和子类中使用该接口(interface),如 this answer 所述。 .
关于php - 我对 Liskov 替换原则有什么误解,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28362180/
所以我实际上正在阅读有关用于删除对象属性的“delete”方法的文档,并且我偶然发现了这个“此外,您不能删除使用 var 关键字声明的全局对象的属性。” 所以我真正理解的是:假设你创建了一个数组: v
我目前正在学习 Javascript,我想知道为什么下面的代码会执行“console.log('why')”。我认为“变量”(var、let、const)仅存储信息,不能自行执行。我不希望以下内容实际
在许多博客和引用文献中,我读到了有关冲洗刷新记录的信息,其中有很多信息会引起头痛和一些误解: 是否为复制的碎片保留了事务日志?为什么? 如果GET /_cat/allocation包含转记录? 超过磁
我有下一个循环: rolling_average_delta_follower=[]; followers=[32,34,36,38,40,42,44,46,48,50,52,54,5
我遇到了多处理问题;我在 linux 2.6.36 上使用 python2.7。我知道使用更高级别的模块或库会容易得多,但我正在尝试使用较低级别的函数(os.fork() 和 os.exec*)以确保
有人可以向我解释一下,为什么这段代码不起作用。我正在浏览周围的一些问题,但找不到答案。可能是因为(大量)缺乏知识。 感谢您提供的任何帮助。 char** sentence = malloc(min);
我的目标是我想用一些 java 代码登录到一个站点,并在登录后做一些工作。(为了编写一些 java cooking 处理,我首先需要了解这一切实际上是如何工作的)问题是我不太清楚如何管理 cookie
给定以下非常简单的结构: struct A { int a; double b; }; (使用 Mac OS 10.9 - Xcode) 结构的大小是 16。我不明白为什么。为什么不是
我刚刚下载了基于 ASP.NET 5 的 music store (microsoft sample projct) 源代码。我不明白为什么 Microsoft 的开发人员在 Controller 中
Closed. This question is not reproducible or was caused by typos。它当前不接受答案。 想改善这个问题吗?更新问题,以便将其作为on-to
我正在阅读 this doc并看到以下片段: The := syntax is shorthand for declaring and initializing a variable, e.g. fo
我在理解描述的 MixColumns 步骤时遇到问题 here . 我知道扩散,这一切都是有道理的,因为它指出每列都被视为多项式并乘以 GF(2^8) 的模。 但是..乘以GF(2 ^ 8)。尽管域仍
我尝试自定义HTML文件输入并编写了最简单的jquery API函数: (function($) { $.fn.selectFileInputGUI = function() {
我对 SSL/TLS 有一个根本性的误解,希望能得到澄清。 按照我的理解,当我获得网站证书时,它包含我的所有信息,并由我的证书颁发机构(VeriSign 或其他任何人)签名。当有人从我的网站请求使用
我们在代码中有一个 NamedTuple,如下所示: from typing import NamedTuple class StandardParameters(NamedTuple): o
我有一个问题,我需要你的帮助: 我正在制作一个 Web 应用程序来访问我需要在类似( ListView 或 DataList )这样的工具中显示他们的员工列表,以直接绑定(bind)数据库中的数据,并
我知道根是: 静态字段 方法参数 本地领域 f-queue 也包含一个指向“将要完成的”对象的指针 cpu 寄存器 <=??? 现在让我们谈谈寄存器。 它们可以包含的代码如下: mov bx, 003
官方例子Timer组件使用this.interval var Timer = React.createClass({ getInitialState: function() { retur
使用 PostGIS 我有两个表,第一个包含 250 个城市的边界,第二个包含世界上所有国家/地区的边界。 我试图影响每个城市所属的国家/地区。下面的查询可以让我得到我想要的结果。 SELECT DI
我正在准备数据库和 SQL 考试,并且正在解决一个练习: 我们有一个包含 4 个表的数据库,代表一家人力资源公司。这些表格是: applicant(a-id,a-name,a-city,years-
我是一名优秀的程序员,十分优秀!