【问题标题】:Force child classes to override a particular function in PHP强制子类覆盖 PHP 中的特定函数
【发布时间】:2013-05-31 01:55:32
【问题描述】:

我正在用 PHP 创建一个报告库并开发了一个名为 ReportView 的抽象类。这将提供报表的基本功能,如生成页眉和页脚、创建参数表单。

在这个类中将有另一个名为 generate_report 的函数。目前它在抽象类中是空的,因为在这个级别我们不知道报告的内容。此外,它还包括一个 render 函数,该函数调用此 generate_report 函数并将输出发送到浏览器。

所以每当子类从 ReportView 继承时,我都需要它必须实现 generate_report 方法,否则 PHP 必须给出错误。是否有任何关键字或方法可以让我们强制执行特定功能。

【问题讨论】:

    标签: php oop


    【解决方案1】:

    执行以下操作:

    abstract class ReportView {
      abstract protected function generate_report();
    
      // snip ...
    
    }
    
    class Report extends ReportView {
      protected function generate_report() { /* snip */ }
    }
    

    任何扩展ReportView 并且不是抽象的类必须实现generate_report(以及它的超类中的任何其他抽象函数)。

    【讨论】:

    • 这对静态方法可行吗?
    • 不。如果您在静态方法中需要此功能,则强烈表明您的代码“过于静态”。您可能需要将一些静态方法移动到它们自己的类中(工厂就是一个典型的例子)。
    【解决方案2】:

    听起来你最好创建一个接口,它会强制你在实现这个接口的类中定义这些方法。

    <?php
    interface ReportInterface {
        public function generate();
    }
    
    class MyReportClass implements ReportInterface {
    }
    

    这里实例化MyReportClass会抛出一个致命错误,告诉你generate()还没有实现。

    编辑:您还可以创建实现此接口的抽象类。您可以让抽象类包含所有扩展类所需的任何方法,并让您的接口定义您需要通过扩展类定义的任何方法。

    【讨论】:

    • 不一定。他可能在基类中有一些实现的方法。
    • 可以是:class MyReport extends ReportView Implements ReportInterface { }
    • @Mark 在这种情况下,OP 可以创建一个实现 ReportInterface 的抽象类。
    • +1 谢谢,可以使用接口,但我认为报表视图类必须只定义一次,因此将 generate_method 抽象为一个不错的选择。
    【解决方案3】:

    你还需要将方法声明为abstract(并且不要给它一个方法体),否则派生类不会被强制实现它。

    或者,您可以实现该方法,但让它只抛出一个异常(不知道您为什么要这样做)。

    最后,如果所有基类中的方法都是“抽象的”(没有主体),那么您可以将类改为接口。

    【讨论】:

    • 基类 ReportView 只需要定义一次,那我为什么需要一个接口呢?
    • 你是什么意思“只需要定义一次”?如果ReportView 中的所有方法都是抽象的,那么您的“纯”抽象类和接口之间实际上并没有太大区别,只是您可以继承多个接口。
    猜你喜欢
    • 2020-12-25
    • 2018-06-15
    • 2021-05-02
    • 2011-05-21
    • 2017-11-18
    • 1970-01-01
    • 1970-01-01
    • 2011-11-14
    • 1970-01-01
    相关资源
    最近更新 更多