Question: Here are my PHP abstraction classes. The bottom most class is one of the classes that will extend the abstract class and leave some of the complex calculation logic to the parent implementation.

The point of the interface class (the top most abstraction) is to force those lower implementations have their own `static public function id($params=false){` method.

```
// My top level abstraction, to be implemented only by "MyAbstraction"
interface MyInterface{
      static public function id();
}

```

---

```
// My second (lower) level of abstraction, to be extended
// by all child classes. This is an abstraction of just the
// common heavy lifting logic, common methods and properties.
// This class is never instantiated, hence the "abstract" modifier.
// Also, this class doesn't override the id() method. It is left
// for the descendant classes to do.

abstract class MyAbstraction implements MyInterface{

    // Some heavy lifting here, including common methods, properties, etc
    // ....
    // ....

     static public function run(){
          $this->id = self::id(); // This is failing with fatal error
     }
}

```

---

```
// This is one of many "children" that only extend the needed methods/properties
class MyImplementation extends MyAbstraction{

     // As you can see, I have implemented the "forced"
     // method, coming from the top most interface abstraction
     static public function id(){
         return 'XXX';
     }
}

```

The end result is that if I call:

```
$o = new MyImplementation();
$o->run();

```

I get a fatal error:
`Fatal error: Cannot call abstract method MyInterface::id();`

Why is `MyAbstraction::run()` calling the `id()` method of its parent (interface) instead of the method found in its child (descendant) class?

Answer: 
"self" is reference to "MyAbstraction" class (itself). So it try to search `MyAbstraction::id()`, and got an error.

1. You shoud use "static" keyword `static::id();`
2. You cannot use $this in static method `($this->id)`.
3. All of your methods are static, so You do not need instantiate an object.
You can do the same with a static call: `MyImplementation::run();`
Try to replace your `self::id()` by `static::id()`.

You use the [Late Static Bindings](http://php.net/manual/en/language.oop5.late-static-bindings.php) of PHP here.