最终的静态类方法是否可行?

时间:2011-11-26 12:51:09

标签: php class inheritance static

我需要一个类来继承另一个类。我在基类中有一个静态函数_init(),我不希望在派生类中继承该方法。我尝试了final关键字,但它不起作用。我该怎么办?

6 个答案:

答案 0 :(得分:7)

你误解了最后的意思。

OOP的基本原则之一是,如果一个类是另一个类的子类,那么该类将获得它继承的类的所有功能。你不能只继承一些超类功能,它是全部或全部。

这样做的原因有点棘手,但一旦你这样做,你就会意识到这是有道理的。也就是说,如果一段代码能够处理特定类的项,那么它也必须能够处理该项的任何子类。如果子类没有其超类的所有功能,则无法执行此操作。

例如,假设您有一个定义与支付网关接口的类。由于所有支付网关都不同,您无法(或至少不应该)实施可与任何可用支付网关连接的单个类。但总的来说,支付网关以相同的基本方式工作。发送请求,包括用户的信用卡详细信息以及您要从卡中扣款的金额。支付网关响应一条消息,说明支付是否被授权。

您可以使用抽象超类来实现这种功能,该超类定义了您通常如何与支付网关接口,然后为您想要使用的每个支付网关创建一个子类(paypal,sagepay,等等)。

由于所有这些子类都继承自相同的基类,因此您可以确定它们都实现了某些方法,并且您可以毫无顾虑地向这些方法发送消息。只要您正在处理的支付类是您的抽象支付类的子类,那么一切都应该有效。

如果其中一个子类无法从抽象超类中实现某些内容,那么您无法确定将特定消息发送到子类是否有效,或者抛出异常。这会使继承变得毫无意义。

最终用PHP(实际上是大多数实现它或类似概念的OOP语言)意味着“这是这个方法的最终实现。如果程序员将我子类化,那么他就不能用自己的实现替换我的最终方法” 。这并不意味着这些方法在子类中不可用,只是你无法改变它们。

如果你真的必须从子类中删除功能,你可以通过重写超类方法并用一个空方法(一个什么都不做)替换它来实现。但不要这样做,因为它会导致上述类型的问题。

通常情况下,如果您遇到在子类中不需要的超类中具有功能的情况,那就是代码味道告诉您可能需要重新考虑您的设计。

答案 1 :(得分:3)

你这样做是错误的。

只是你希望扩展类有一个方法,这意味着你违反了Liskov's substitution principle ..如果阅读很难:这里是 {{3} 解释它。

如果您遇到某种情况,当您必须在将其发布到应用程序之前对对象执行某种“工作”时,则应该使用Factory / Builder。

class FooBuilder
{
   public function create( $external_condition )
   {
      $object = new Foo;
      if ( $external_condition->has_happened() )
      {
         $object->set_condition( $external_condition );
      }else{
         $object->do_something_else();
      }
      return $object;
   }
}

现在,您始终通过Foo制作FooBuilder课程的实例,广告Foo广告时,它没有任何无用的方法。

此外,我认为类中的静态方法是程序编程的标志。静态变量只不过是包含在伪装成类的命名空间中的全局变量。

答案 2 :(得分:3)

静态意味着每个类一个,而不是每个对象一个,无论可能存在多少个类实例。这意味着您可以在不创建类实例的情况下使用它们。静态方法是隐式最终的,因为覆盖是基于对象的类型完成的,而静态方法是附加到类而不是对象。只要原始方法未声明为final,超类中的静态方法可以被子类中的另一个静态方法遮蔽。但是,您不能使用非静态方法覆盖静态方法。换句话说,您不能将静态方法更改为子类中的实例方法。

最终的课程不能延期,即最终的课程不能被分类。继承其类时,不能覆盖最终方法。您无法更改最终变量的值(是常量)。

答案 3 :(得分:2)

在POO中,如果一个B类继承了另一个A类,那么B类将包含A类的所有方法,这是POO遗产的基础。所以I don't want that method to be inherited in the derived class在这里毫无意义。你应该看看另一种机制来做到这一点。

另外,是most个案例,这种情况(你不希望派生类继承一个方法)表明你的派生类根本不应该继承,你应该在哪里使用另一个系统。

答案 4 :(得分:1)

检查此示例:

class foo
{
  private static $stuff = array('key1' => 1, 'key2' => 2);

  public final static function getstuff()
  {
   return self::$stuff;
  }
}

答案 5 :(得分:1)

我同意pomeh在PHP中的OOP,我还想补充一点,当与方法一起使用时,FINAL关键字实际上意味着该方法无法被覆盖。该方法将继承。