php中接口的用途是什么?

时间:2010-12-07 01:33:55

标签: php interface

如果我在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;
}
?>

4 个答案:

答案 0 :(得分:9)

这就是PHP中接口良好的原因:

interface Printable{
    public function display();
}

function display(Printable $obj){
    $obj->display();
}

它要求进入该函数的任何变量都是Printable的实例。因此,如果要使用该功能,则强制任何使用您的代码的人实现该接口。

PHP 5.1 http://php.net/manual/en/language.oop5.typehinting.php

如果要确保其他人无法使用特定方法或类的变量,则需要将这些方法和变量定义为private。这将使它们无法被除特定类之外的任何东西使用。 (甚至扩展你的类的类都不能使用它们)

答案 1 :(得分:6)

您所要求的只能使用静态类型语言,并且由于PHP是动态类型的,因此简短的答案是不可能。

例如,在Java中,createMyInterface可以返回IMyInterface,并且此对象上唯一可能的操作是在接口本身中定义的操作。当然,该对象实际上是ConcreteImplOfMyInterface类型,因此您始终可以将其强制转换为该类型以访问其他字段/方法。

PHP没有声明的类型,因此从函数返回的只是一个“变量” - 它没有类型。并且由于没有类型,所有字段/方法查找都是动态的,因此始终可以访问对象中“存在”的任何内容。

在某种程度上,接口在PHP等语言中的使用确实有限 - 任何实现接口的类都必须实现其所有方法,但由于无法保证函数在第一个函数中可以返回什么这个地方基本上没有任何保证。您可以做的最好的事情是使用instanceof来检查未知变量是否实现了给定的接口。

答案 2 :(得分:2)

由于PHP是一种动态语言,因此它意味着对所有类成员的访问将在运行时解析。这意味着如果我有代码调用$ foo-&gt; bar()并且我在$ foo中得到了具有bar()方法的对象,那么即使它可能不是我想要的方法bar()也会被调用在一些其他对象上调用但是其他一些方法,巧合的命名是相同的。

然而,话虽如此,您可以通过使用类型化参数来提供一些保护,使函数只接受特定对象:

function doingSomething(IMyInterface $foo) {
  $foo->doSomething();
}

但是,您仍然无法禁止任何人实现IMyInterface,然后编写接受IMyInterface的函数,但使用它就好像它是某些更高级别的对象一样。正如我所说,这是由于PHP是动态语言。

答案 3 :(得分:1)

将方法设为私有。

return $myInterface.NotPartOfInterface;

这有用吗?我认为不应该。我想你想要::运算符。

.仅用于连接字符串。