【问题标题】:PHP: Can I Use Fields In Interfaces?PHP:我可以在接口中使用字段吗?
【发布时间】:2011-01-16 03:07:47
【问题描述】:

在 PHP 中,我可以指定一个具有字段的接口,还是 PHP 接口仅限于函数?

<?php
interface IFoo
{
    public $field;
    public function DoSomething();
    public function DoSomethingElse();
}
?>

如果没有,我意识到我可以在接口中将 getter 作为函数公开:

public GetField();

【问题讨论】:

  • 警告:如果你因为提出这个问题而投了反对票,请不要惊讶 - 检查 PHP 手册的 OOP 部分。
  • 是的,快速浏览手册显示他们只使用接口中的函数。可能只是跳过了那部分。无论哪种情况,我只是想确定一下。

标签: php interface


【解决方案1】:

接口仅用于支持方法。

这是因为接口的存在是为了提供一个公共 API,然后其他对象可以访问该 API。

可公开访问的属性实际上会违反实现接口的类中的数据封装。

【讨论】:

    【解决方案2】:

    您不能在 interface 中指定属性:只允许使用方法(并且有意义,因为接口的目标是指定 API)


    在 PHP 中,尝试在接口中定义属性会引发致命错误:这部分代码:

    interface A {
      public $test;
    }
    

    会给你:

    Fatal error: Interfaces may not include member variables in...
    

    【讨论】:

      【解决方案3】:

      您不能指定成员。你必须通过 getter 和 setter 来表明它们的存在,就像你做的那样。但是,您可以指定常量:

      interface IFoo
      {
          const foo = 'bar';    
          public function DoSomething();
      }
      

      http://www.php.net/manual/en/language.oop5.interfaces.php

      【讨论】:

        【解决方案4】:

        迟到的答案,但要获得此处所需的功能,您可能需要考虑一个包含您的字段的抽象类。抽象类看起来像这样:

        abstract class Foo
        {
            public $member;
        }
        

        虽然你仍然可以拥有界面:

        interface IFoo
        {
            public function someFunction();
        }
        

        那么你的子类是这样的:

        class bar extends Foo implements IFoo
        {
            public function __construct($memberValue = "")
            {
                // Set the value of the member from the abstract class
                $this->member = $memberValue;
            }
        
            public function someFunction()
            {
                // Echo the member from the abstract class
                echo $this->member;
            }
        }
        

        对于那些仍然好奇和感兴趣的人来说,还有另一种解决方案。 :)

        【讨论】:

        • 我很好奇也很感兴趣。如何保证会员的存在? :)
        • Class Foo 应该实现接口'IFoo',它是抽象的,它会清楚地显示Foo 目的:简化接口实现。
        • 同意,@PeterM。抽象类也可以实现接口而不是最终类。取决于你是否总是希望强制执行someFunction()
        • 对变量使用抽象类很可能会变成好的代码设计。我投票赞成这是一个合理的答案:]
        【解决方案5】:

        使用getter setter。但是,在许多类中实现许多 getter 和 setter 可能会很乏味,并且会使类代码变得混乱。还有you repeat yourself

        从 PHP 5.4 开始,您可以使用 traits 为类提供字段和方法,即:

        interface IFoo
        {
            public function DoSomething();
            public function DoSomethingElse();
            public function setField($value);
            public function getField();
        }
        
        trait WithField
        {
            private $_field;
            public function setField($value)
            {
                $this->_field = $value;
            }
            public function getField()
            {
                return $this->field;
            }
        }
        
        class Bar implements IFoo
        {
            use WithField;
        
            public function DoSomething()
            {
                echo $this->getField();
            }
            public function DoSomethingElse()
            {
                echo $this->setField('blah');
            }
        }
        

        如果您必须从某些基类继承并需要实现某些接口,这特别有用。

        class CooCoo extends Bird implements IFoo
        {
            use WithField;
        
            public function DoSomething()
            {
                echo $this->getField();
            }
            public function DoSomethingElse()
            {
                echo $this->setField('blah');
            }
        }
        

        【讨论】:

        • 但是对于抽象类,你只能从这个类继承。有了特征和接口,你就有了多继承。生病添加它来回答。
        猜你喜欢
        • 2012-10-31
        • 1970-01-01
        • 2013-05-28
        • 1970-01-01
        • 2018-04-04
        • 2013-08-02
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多