Mihai Bujanca
Mihai Bujanca

Reputation: 4209

Override interface method PHP

I have the following code

class Model_MyAbstractClass {
}

class Model_MyClass extends Model_MyAbstractClass {

}
interface doStuff {

    function update(Model_MyAbstractClass $model);

}
class Mapper_MyClass implements doStuff{
     function update(Model_MyClass $model){
      }
}

So why doesn't this work in PHP? Model_MyClass is still a Model_MyAbstractClass. I have 5 classes (maybe I'll have more) with similar methods. The whole difference is that each mapper has some model, all of them extend Model_MyAbstractClass.
If indeed there is no way of doing this, the only solutions left are: make an interface for each of them, with the only differences being the params (not DRY at all).
Check in each of the functions if the Model_MyAbstractClass is instance of Model_MyClass needed and throw an error - which seems like a silly strategy since I should be requiring explicitly the needed type of parameter.

Upvotes: 0

Views: 92

Answers (2)

Christian Gollhardt
Christian Gollhardt

Reputation: 17004

It is normal, that this is not working.

Your interface let assume, that you can pass any Model_MyAbstractClass to this function:

function update(Model_MyAbstractClass $model);

Here, you expect only a Model_MyClass:

class Mapper_MyClass implements doStuff{
     function update(Model_MyClass $model){    
     }
}

Sure, Model_MyClass is an instance of Model_MyAbstractClass. But the interface would assume, that you also can pass the class Model_SomeOtherClass which is extended from Model_MyAbstractClass.

Summary: You should be able to handle ANY Model_MyAbstractClass NOT ONLY Model_MyClass


What you possible Need:

class Mapper_MyClass implements doStuff
{
    function update(Model_MyAbstractClass $model)
    {
        //Do stuff on Model_MyAbstractClass

        //...

        if ($model instanceof Model_MyClass) {
            //Do additional stuff on Model_MyClass

            //...
        }
    }
}

Maybe you running into the same problem like me, which can be easily solved via C# and Java. For me it was, i wanted a Generic Base Class. So something like this:

abstract class Foo<T> {
    function update(T $model)
}

class Bar extends Foo<Model_MyClass> {
}

This is current not possible with plain PHP, but Facebook's Hack made it possible. Problem is, this was no option for me, but maybe for you. I have done it with the way of using the instanceof as described above.

Upvotes: 1

Artemkller545
Artemkller545

Reputation: 999

Your problem is not related to PHP, but is more of a misunderstanding how interfaces work in OOP concept.

From your code, interface doStuff has a method which takes Model_MyAbstractClass as its parameter, means the parameter instance will always be displayed as Model_MyAbstractClass and not anything else, doesn't matter if the given instance is instance of Model_MyAbstractClass, like in your example.

In an OOP language, such as Java, you will receive an error like this:

The method update(Model_MyAbstractClass) of type Mapper_MyClass must override or implement a supertype method

However, in PHP you can do instanceof checks, and in OOP languages you can cast to Model_MyClass

Upvotes: 0

Related Questions