【问题标题】:Given a PHP class would be the best and simplest way to override one or two of its methods with one of your own?给定一个 PHP 类将是用您自己的一种方法覆盖其中一种或两种方法的最佳和最简单的方法吗?
【发布时间】:2011-02-22 11:44:02
【问题描述】:

这是目标。我有一个 PHP 类,并且我想用自己的方法覆盖其中的一两个方法。据我了解 OOP(在 PHP 和一般情况下),我可以编写一个子类来扩展它并覆盖相关方法的功能。

但是,我想知道这是否是完成此任务的最佳方式,以及这是否适合子类使用,或者 PHP 中是否有更好的东西来解决我正在尝试做的事情。

【问题讨论】:

    标签: php oop methods overriding


    【解决方案1】:

    是的,这是最好的方法。扩展类的想法是提供额外或更具体的功能。

    【讨论】:

      【解决方案2】:

      是的。这正是您使用继承的目的。

      不过,一个好的原则是确保您的新继承类“is-a”基类。

      就像Human 是一个Mammal。不要仅仅因为外星人做了很多人类做的事情就去做Alien extends Human

      【讨论】:

      • 是的,指出得很好。我记得几年前,当我第一次在 php 中开始 OOP 时,完全按照您的描述进行操作,让自己陷入了一些混乱。这些天来,我发现,即使是在一个复杂的项目中,我的课程都很短而且很简单。复杂性来自于你如何组合这些类。如果你的大脑正在试图编写一些庞大的方法,因为你需要处理很多案例或变体,那么你可能想回顾一下你的类的结构
      【解决方案3】:

      那么,您是在问重写方法(需要扩展超类)是否是重写方法的最佳方式?是的。

      这是子类最重要的用途。事实上,多态性是 OOP 的核心。另一个用途是提供新的属性/方法,但这通常是不够的。

      【讨论】:

        【解决方案4】:
        class oldClass {
          public function methodToOverride() {
            echo 'oh hai';
          }
        }
        
        class childClass extends oldClass {
          public function methodToOverride($arg, $arg2) {
            // your custom code
            echo 'hai world ' . $arg . ' ' . $arg2;
        
            // if you need to still call the parent class
            parent::methodToOverride();
          }
        }
        
        $child = new childClass();
        $child->methodToOverride('nom', 'nom');
        

        【讨论】:

        • 只是让你知道,那不是我,这适用于任何花时间回答 n00b(例如我自己)问题的人:我感谢任何人阅读我的问题并给予给我一个答案,我永远不会给任何人一个大拇指或-1。
        【解决方案5】:

        听起来你在正确的轨道上。

        对于您想要覆盖的方法,您可能想要:

        • 确保您没有改变方法的意图
        • 了解是否必须在内部调用基类的方法以及何时调用

        【讨论】:

          【解决方案6】:

          唯一的另一种方法是创建一个通用的“超类”......

          class SuperClass {
              protected $obj = null;
              protected $overrides = array();
          
              public function __construct($obj) {
                  if (!is_object($obj)) {
                      throw new InvalidArgumentException('Argument is not an object');
                  }
                  $this->obj = $obj;
              }
          
              public function __call($method, $args) {
                  $method = strtolower($method);
                  if (isset($this->overrides[$method])) {
                      array_unshift($args, $this);
                      return call_user_func_array($this->overrides[$method], $args);
                  } elseif (is_callable(array($this->obj, $method))) {
                      return call_user_func_array(array($this->obj, $method), $args);
                  } else {
                      throw new BadMethodCallException('Invalid Method Called');
                  }
              }
          
              public function __get($var) {
                  return isset($this->obj->$var) ? $this->obj->$var : null;
              }
          
              public function __set($var, $value) {
                  $this->obj->$var = $value;
              }
          
              public function addOverride($method, $callback) {
                  $this->overrides[strtolower($method)] = $callback;
              }
          }
          

          这并不总是最好的解决方案,但在某些情况下可能会使用类似的东西。它可以让您在运行时向任何对象“添加”和“覆盖”方法。

          更好的通用解决方案是简单地在子类中扩展类...但是上面的“超类”确实有一些用途...

          【讨论】:

            【解决方案7】:

            我在这里没有看到的另一条路线是质疑提取一个抽象类并让两个类扩展它是否会更好。当然,您需要能够为此更改第一个类的代码(即,如果该类来自开源库,您可能会避免更改代码)。

            【讨论】:

              【解决方案8】:

              你在正确的轨道上

              【讨论】:

                猜你喜欢
                • 2016-11-08
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                • 2013-02-10
                • 2017-02-16
                • 1970-01-01
                相关资源
                最近更新 更多