Is a final static class method possible?

2019-04-14 06:46发布

问题:

I need a class to inherit another class. I have a static function _init() in the base class, and I don't want that method to be inherited in the derived class. I tried the final keyword but it's not working. What should I do?

回答1:

You're misunderstanding what final means.

One of the foundation principles of OOP is that if a class is a subclass of another class, then that class gets all the functionality of the class it inherits from. You can't inherit just some of the superclass functionality, it's all or nothing.

The reason for this is a bit tricky to get to grips with but once you do, you'll realise that it makes sense. Namely, if a piece of code is able to process items of a particular class, then it must also be able to process any subclass of the item as well. If a subclass didn't have all the functionality of its superclass, you couldn't do that.

For example, imagine you have a class that defines interfacing with a payment gateway. As all payment gateways are different, you couldn't (or at least shouldn't) implement a single class that can interface with any of the payment gateways that are available. But in general, payment gateways work in the same basic way. A request is sent, including a user's credit card details and amount you want to debit from the card. The payment gateway responds with a message saying whether payment was authorized or not.

You'd implement that kind of functionality with an abstract superclass that defines how you interface with payment gateways in general, then you'd create a subclass for each payment gateway you want to use (paypal, sagepay, whatever).

As all these subclasses inherit from the same base class, you can be certain that they all implement certain methods, and you can send messages to those methods without worry. As long as the payment class you're dealing with is a subclass of your abstract payment class, then everything should work.

If one of the subclasses was able to not implement something from the abstract superclass, then you couldn't be sure that sending a particular message to a subclass would work, or throw an exception. This would make inheritance rather pointless.

Final in PHP (and indeed most OOP languages that implement it or similar concepts) means "This is the final implementation of this method. If a programmer subclasses me, then he can't replace my final methods with his own implementation". It doesn't mean that the methods will not be available in the subclass, just that you can't change them.

If you really must remove functionality from a subclass, you can do it by overriding the superclass method and replacing it with an empty method (one that does nothing). But don't do that, as it will cause problems of the type discussed above.

Generally, if you run into situations where you have functionality in a superclass that you don't need in a subclass, it's a code smell that's telling you that you might need to rethink your design.



回答2:

Static means one per class, not one for each object no matter how many instance of a class might exist. This means that you can use them without creating an instance of a class.Static methods are implicitly final, because overriding is done based on the type of the object, and static methods are attached to a class, not an object. A static method in a superclass can be shadowed by another static method in a subclass, as long as the original method was not declared final. However, you can't override a static method with a nonstatic method. In other words, you can't change a static method into an instance method in a subclass.

A final class can't be extended ie., final class may not be subclassed. A final method can't be overridden when its class is inherited. You can't change value of a final variable (is a constant).



回答3:

You are doing it the wrong way.

Just the fact that you want the extended class to not have a method, means you are violating Liskov's substitution principle .. if reading is hard: here is a picture explaining it.

If you have a situation, when you have to perform some sort of "work" on object before you release it into the application, then you should use a Factory/Builder for it.

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;
   }
}

Now you always make instances of Foo class through FooBuilder, ad when you extend Foo, it does not have any useless methods.

Additionally, i would argue that static methods in classes are a sign of procedural programing. And static variables are nothing else but global variables wrapped in namespace masquerading as class.



回答4:

In POO, if a class B inherits another class A, the class B will contain all the methods from class A, this is the foundation of POO heritage. So I don't want that method to be inherited in the derived class make no sense here. You should look at another mechanism to do that.

Also, is most cases, such situation (where you don't want the derived class inherits a method) is a sign that your derived class should not inherit at all, and where you should use another system.



回答5:

Check this example:

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

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



回答6:

I would agree with pomeh on OOP in PHP and I would also want to add that the FINAL keyword when used with a method actually means that the method cannot be overridden. The method will be inherited though.