实现接口的抽象类是否也需要声明接口方法?

时间:2018-04-18 06:32:15

标签: php oop

我已经开始在PHP中使用界面了,在阅读了文档后,关于界面和抽象类,我很清楚:

  1. 接口声明公共方法。所以任何实现它的类都必须实现这些方法。
  2. 抽象类更像是一个部分完成的类,在扩展时需要更多细节。
  3. 所以我试图创建一个实现常用方法的抽象类,但是对于可能基于子类更改的专用方法,它们是抽象的。

    但是我没有使用抽象方法,而是考虑使用接口。原因是,我需要一些静态方法,我将使用后期静态绑定。所以我提出了以下模式

    <?php
    interface Element {
        /**
         * Constructor function. Must pass existing config, or leave as
         * is for new element, where the default will be used instead.
         *
         * @param array $config Element configuration.
         */
        public function __construct( $config = [] );
    
        /**
         * Get the definition of the Element.
         *
         * @return array An array with 'title', 'description' and 'type'
         */
        public static function get_definition();
    
        /**
         * Get Element config variable.
         *
         * @return array Associative array of Element Config.
         */
        public function get_config();
    
        /**
         * Set Element config variable.
         *
         * @param array $config New configuration variable.
         *
         * @return void
         */
        public function set_config( $config );
    }
    
    abstract class Base implements Element {
    
        /**
         * Element configuration variable
         *
         * @var array
         */
        protected $config = [];
    
        /**
         * Get Element config variable.
         *
         * @return array Associative array of Element Config.
         */
        public function get_config() {
            return $this->config;
        }
    
        /**
         * Create an eForm Element instance
         *
         * @param array $config Element config.
         */
        public function __construct( $config = [] ) {
            $this->set_config( $config );
        }
    }
    
    class MyElement extends Base {
    
        public static function get_definition() {
            return [
                'type' => 'MyElement',
            ];
        }
    
        public function set_config( $config ) {
            // Do something here
            $this->config = $config;
        }
    }
    
    $element = new MyElement( [
        'foo' => 'bar',
    ] );
    
    print_r( $element->get_config() );
    

    这适用于PHP7。正如你所看到的,我还没有声明像

    这样的东西
    abstract public function set_config( $config );
    

    在抽象类中。

    由于该方法是在MyElement类中实现的,因此它可以正常工作。如果我没有在MyElement类中实现该方法,那么我会收到错误

    PHP Fatal error: Class MyElement contains 1 abstract method and must therefore be declared abstract or implement the remaining methods (Element::set_config)

    这正是我想要的。

    所以我的问题是,实施模式是否正确?这适用于PHP 7.1,但PHP 5.4+的行为是否相同?或者我在做反模式的事情?

1 个答案:

答案 0 :(得分:-2)

回答我自己的问题

抽象类不需要从接口实现方法。

抽象类本质上被认为是“不完整的”,因此默认情况下,它从接口继承的方法被视为abstract,如果它没有实现它。

错误消息

中也很清楚

PHP Fatal error: Class MyElement contains 1 abstract method and must therefore be declared abstract or implement the remaining methods (Element::set_config)

但是因为类Base已经被声明为abstract,所以它不需要实现其余的方法,只需要继承自Base类的非抽象类。

我在这里运行测试https://3v4l.org/8NqqW,你可以看到启动PHP 5.4 upword,输出是一样的。