Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Alternative model for PHP abstract static class methods

Ok, so I've read lots of posts on here about this, but I think this is a specific and new question.

I want the functionality of what lots of us on here wrongly call an "abstract static method". That is: I want a class that insists classes that extend it implement certain static methods.

It seems there are two roads round the much discussed problem of not allowing abstract static, but both seem inelegant.

Problem

The following generates an error: "PHP Strict Standards: Static function A::fn() should not be abstract".

<?php
abstract class A
{
     abstract static public function fn();
}

class B extends A
{
    static public function fn()
    {
         // does something on class vars etc.
    }
}

Solution 1: use Interfaces

<?php
interface iA {
    static function fn();
}


abstract class A implements iA 
{
} // obviously this would have other stuff in it in reality

class B extends A
{
    static public function fn()
    {
         // does something on class vars etc.
    }
}

The problem with this is that an interface assumes (dictates) that all the methods be public. So while this achieves the goal of insisting that sub-classes of an abstract class have certain static methods, it can only be used for public methods; there is still no way to ensure subclasses of A implement a protected static method.

Protected static methods are useful when the method works entirely on static data but ought not to be called from 'outside'.

Solution 2: exceptions

abstract class A
{
     static public function fn()
     {  
         throw new Exception(get_called_class() . " must implement fn()");
     }

}

class B extends A
{
    static public function fn()
    {
         // does something on class vars etc.
    }
}

This works at runtime if fn() when called. But it's not useful to have to deal with coding syntax mistakes at runtime. And while this could be a hack for one method, it's a lot more code for each method.

Is there something so wrong with this design that the language rightly forbids it? Seems odd that there are various ways to insist subclasses provide most types of method, but not static ones.

like image 433
artfulrobot Avatar asked Feb 15 '13 12:02

artfulrobot


1 Answers

It's because static methods belong to the class where they are defined. A::fn() and B::fn() are two different methods, regardless of the inheritance tree. So it makes little sense to define A::fn() as abstract.

Maybe your methods in question should not be abstract at all? If you want to use any kind of polymorphism, there should be objects involved.

like image 106
Fabian Schmengler Avatar answered Oct 27 '22 01:10

Fabian Schmengler