是否可以具有包含私有/受保护方法的接口?


76

PHP 5中是否可能具有包含私有/受保护方法的接口?

现在我有:

interface iService
{
    private method1();
}

抛出一个错误:

解析错误:语法错误,意外的T_STRING,预期的T_VARIABLE

我只想确认某个接口只能包含公共方法。


2
我发现答案令人失望。我也想要支持受保护/私有方法的接口。例如,我有一个类,其中抽象实现的公共方法依赖于子类实现的受保护方法。我想使用一个接口来要求子类实现抽象公共方法所需的受保护方法。
Stoutie 2012年

4
为此,请使用抽象基类。您可以将两种方法结合起来:接口中的公共方法,在定义(并依赖)抽象受保护方法的抽象基类中实现这些方法。
Stijn de Witt 2014年

2
如果可以声明私有方法或受保护的方法,则private function method1 ();不是private method1();
tvanc 2014年

Answers:



20

接口用于描述实现该接口的类的公共方法。接口中永远不能有私有方法。假定接口中的任何方法都在使用中,不应更改。

接口是PHP链接,但这是OO编程中的标准。


1
在其他语言(如java)中,您可以在接口中使用访问修饰符。
User123456

9

通常,接口只能具有公共成员,因为接口的唯一功能是要继承。

从PHPfreaks.com教程中:

PHP5具有接口。不要从更广义的意义上与接口混淆,interface关键字创建一个实体,该实体可用于在类上强制使用公共接口,而不必像抽象类那样扩展它们。而是实现了一个接口。

接口与抽象类不同。首先,它们实际上不是课程。他们没有定义属性,也没有定义任何行为。接口中声明的方法必须在实现该接口的类中声明。

因为从广义上讲,接口是对象与其他代码交互方式的定义,所以所有方法都必须声明为公共方法(请参阅本章中有关可见性的部分)。使用抽象类,抽象方法可以具有任何可见性,但是扩展类必须使其实现使用相同(或更弱)的可见性。实现接口会将方法作为抽象方法添加到主题类,否则将导致如下错误:

致命错误:SomeConcreteClass类包含n个抽象方法,因此必须声明为抽象或实现其余方法是的,抽象类可以实现接口。


4
这太糟糕了。因为我希望接口需要一个公共方法,该方法在抽象类中实现,所以该方法依赖于接口也强制执行的受保护方法。这样,抽象类可以提供公共接口,但是由子类来实现基础逻辑。有道理?
Stoutie 2012年

4
似乎您希望该子类实现的方法是抽象的。然后,任何子类都必须实现它。但这与接口无关。
2012年

6

接口是类型声明。一种类型是一组值,再加上一组可以从外部进行的操作。私有方法不适合这张照片。

interface T {
  public /*int*/ function f(array $a);
}
interface U {
  public /*T*/ function g(T $t);
}

class C implements U {
    public function g(T $t) {
        ...
        $x = $t->f();
        ...
    }
}

接口非常有用,因为它们可以很好地说明对象的接口。对象如何与环境通信。

现在假设T::f可以宣布为私有。这对其他对象有什么用?它不能从外部调用,也不会成为其接口的一部分。


同意...但是可以受到保护吗?由于抽象类允许...
asdfasdfasdf


0

NO,接口中的任何方法都永远不会拥有私有或受保护的访问标识符。

**在接口中声明的所有方法必须是公共的;这就是界面的本质。

关于界面的其他一些有趣的事实

可以使用extends运算符像类一样扩展接口。它们只能扩展其他接口。(来源:https : //www.php.net/manual/zh/language.oop5.interfaces.php

请注意,可以在接口中声明构造函数,这在某些情况下(例如供工厂使用)很有用。子类中的签名应该相同。

在您的情况下,甚至另一个问题是-函数声明中缺少function关键字。 它应该是

interface iService
{
    public function method1();
}

0

如前所述,接口只能定义公开可见的方法。我想展示一个如何处理受保护方法的示例。要强加使用特定的受保护方法,可以创建一个实现该接口的抽象类。

如果抽象类已经可以处理某些工作量,以简化实际实现,则这尤其有意义。例如,在这里,抽象类负责实例化结果对象,这总是需要的:

首先,界面。

interface iService
{
   /**
    * The method expects an instance of ServiceResult to be returned.
    * @return ServiceResult
    */
    public function doSomething();
}

然后,抽象类定义内部方法结构:

abstract class AbstractService implements iService
{
    public function doSomething()
    {
        // prepare the result instance, so extending classes
        // do not have to do it manually themselves.
        $result = new ServiceResult();

        $this->process($result);

        return $result;
    }

   /**
    * Force all classes that extend this to implement
    * this method.
    *
    * @param ServiceResult $result
    */
    abstract protected function process($result);
}

实际执行该类的类自动从abstact类继承该接口,并且仅需要实现受保护的方法。

class ExampleService extends AbstractService
{
    protected function process($result)
    {
         $result->setSuccess('All done');
    }
}

这样,接口可以履行公共合同,并且通过AbstractService类可以满足内部合同。应用程序只需要AbstractService在适用的情况下强制使用该类。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.