0

I mistakenly defined the method signature as

abstract static public function mapAttributeKeys(array $attributes)

It works properly, but while I'm refactoring the code, I see it is not looks well and it should be as following according to my habit.

abstract public static function mapAttributeKeys(array $attributes)

I little surprised how these two works. I was thinking the above syntax is a wrong syntax.

So these two are working. Is there any reason why the definition is not stricted ? Or something like a pattern match here ?

My actual aim is to learn why these flexibility is exist ? Is there any special approach or implementation trick exist ?

Updated :

I saw https://stackoverflow.com/a/10740068/1147648 this explanation really meaningful.

An abstract function will never be static, in any kind of language

if it is true, why there is implementation exist ?

Even in symfony validator loader.

https://github.com/symfony/validator/blob/master/Tests/Mapping/Loader/AbstractStaticMethodLoader.php

Community
  • 1
  • 1
FZE
  • 1,587
  • 12
  • 35
  • 2
    You can put these keywords in any order you want. The [recommended order](http://www.php-fig.org/psr/psr-2/#1-overview) is the alphabetical one: `abstract` comes first, then `private/protected/public` and finally `static`. – axiac Feb 08 '16 at 13:29

1 Answers1

7

abstract, public and static are all modifier keywords for a function definition. There's no specific order in which they need to be stated, they're all of equivalent importance and do not rely on or interact with one another in any way.

A big, blue, round ball is the same as a blue, round, big ball.


An abstract function will never be static, in any kind of language

Jein.

The use of abstract is to force a subclass to implement a particular method, so the parent class/users of the parent class can rely on the method being there:

abstract class Foo {
    abstract public function bar();
}

function baz(Foo $foo) {
    $foo->bar();
}

baz doesn't know what specific instance of Foo it'll receive, but it can be sure it'll have a bar method.

Now, static methods can only be called on the class itself:

Foo::bar();

If you're writing this, you know what class you're calling bar on. You're not going to substitute Foo here; Foo is hardcoded, it is not a variable as in the case with $foo.* So... you already know what you're getting and don't need some abstract base class to enforce some interface for you.

* This is true even if you use a string variable to dynamically change the class name. The point is that you can't type hint against that, so you're on your own. Class interfaces, which includes abstract methods, only become useful and interesting with type hinting, which can only be done with object instances.

It's possible to enforce static methods to be defined on child classes, it just usually doesn't make a whole lot of practical sense.

deceze
  • 510,633
  • 85
  • 743
  • 889
  • 1
    Perfect, I didn't know this. I accept your answer for my base question, I updated my question could you please clarify me about updated question ? – FZE Feb 08 '16 at 13:33
  • 1
    I see very clear explanation, thanks for the afford. – FZE Feb 08 '16 at 13:49