【发布时间】:2019-01-17 23:47:06
【问题描述】:
让我们想象一下,我们有以下接口声明。
<?php
namespace App\Sample;
interface A
{
public function doSomething();
}
以及实现接口A的类B。
<?php
namespace App\Sample;
class B implements A
{
public function doSomething()
{
//do something
}
public function doBOnlyThing()
{
//do thing that specific to B
}
}
类C 将依赖于接口A。
<?php
namespace App\Sample;
class C
{
private $a;
public function __construct(A $a)
{
$this->a = $a;
}
public function doManyThing()
{
//this call is OK
$this->a->doSomething();
//if $this->a is instance of B,
//PHP does allow following call
//how to prevent this?
$this->a->doBOnlyThing();
}
}
...
(new C(new B()))->doManyThing();
如果将实例类 B 传递给 C,PHP 确实允许调用 B 的任何公共方法,即使我们键入提示构造函数只接受 A 接口。
如何在 PHP 的帮助下避免这种情况,而不是依赖任何团队成员来遵守接口规范?
更新:假设我不能将 doBOnlyThing() 方法设为私有,因为它在其他地方是必需的,或者它是我无法更改的第三方库的一部分。
【问题讨论】:
-
你不能把
B::doBOnlyThing设置成private function吗? -
@NiettheDarkAbsol 让我们说,我不能将其设为私有,因为它在其他地方使用。
-
我听不懂。无法实例化接口,您在构造函数中输入了
A接口并发送了一个对象B来实现它(您不能发送A实例)。这有什么问题?看到投票我错过了一些东西。 -
@AymDev 如果您在 Java 中使用接口,我正在寻找的是相似的。如果您有声明为接口的属性并尝试调用不属于接口规范的方法,编译器会触发编译错误。
-
如果获得 "only B things" 方法有帮助:
$A = class_implements(($b = new B)); $A_methods = get_class_methods(array_shift($A)); echo '<pre>' . print_r(array_diff(get_class_methods($b), $A_methods), true) . '</pre>';
标签: php interface type-hinting