Reputation: 4209
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
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
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