如果我在PHP中定义一个接口,以及一个创建该接口实例的工厂类,有什么办法可以强制客户端代码只使用接口而不是底层的具体类?根据我的理解,客户端也能够实际使用底层类中的任何公共函数/字段.
这是一个例子:
<?php
interface IMyInterface
{
public function doSomething();
}
?>
<?php
class ConcreteImplOfMyInterface implements IMyInterface
{
const NotPartOfInterface = 'youcantseeme';
public function doSomething()
{
}
}
?>
<?php
class MyInterfaceFactory
{
public static function createMyInterface()
{
return new ConcreteImplOfMyInterface();
}
}
?>
<?php
function client()
{
$myInterface = MyInterfaceFactory::createMyInterface();
return $myInterface::NotPartOfInterface;
}
?>
Run Code Online (Sandbox Code Playgroud)
这就是PHP中接口良好的原因:
interface Printable{
public function display();
}
function display(Printable $obj){
$obj->display();
}
Run Code Online (Sandbox Code Playgroud)
它要求进入该函数的任何变量都是Printable的实例.因此,如果要使用该功能,则强制任何使用您的代码的人实现该接口.
PHP 5.1 http://php.net/manual/en/language.oop5.typehinting.php
如果要确保其他人无法使用特定方法或类的变量,则需要将这些方法和变量定义为private.这将使它们无法被除特定类之外的任何东西使用.(甚至扩展你的类的类都不能使用它们)
您要求的只能使用静态类型语言,并且因为PHP是动态类型的,所以简短的答案是它不可能.
例如,在Java中,createMyInterface可以返回一个IMyInterface,并且该对象上唯一可能的操作是在接口本身中定义的操作.当然,对象实际上是类型ConcreteImplOfMyInterface,因此您始终可以将其强制转换为该类型以访问其他字段/方法.
PHP没有声明的类型,因此从函数返回的只是一个"变量" - 它没有类型.并且由于没有类型,所有字段/方法查找都是动态的,因此始终可以访问对象中"存在"的任何内容.
在某种程度上,接口在PHP等语言中的使用确实有限 - 任何实现接口的类都必须实现其所有方法,但由于无法保证函数首先可以返回什么,所以基本上不保证任何东西.您可以做的最好的事情是用于instanceof检查未知变量是否实现给定的接口.
| 归档时间: |
|
| 查看次数: |
1068 次 |
| 最近记录: |