I have a need in a current application to extend interfaces and possibly
re-define (change signature) some of the inherited methods in the child
interface.
e.g.
interface Foo {
public function __construct(MyCls $var);
public function myFunction();
}
interface Bar extends Foo {
public function __construct(MyCls $var, $var2 = null);
public function myOtherFunction();
}
class A implements Bar {
public function __construct(MyCls $var, $var2 = null) {
// ...
}
public function myFunction() {
// ...
}
public function myOtherFunction() {
// ...
}
}
This is not currently possible in PHP5b4, due to the (new?) "Can't
inherit abstract function" errors generated by the engine. I.e. if I
try to redefine __construct() I will get an error.
The need for this capability is probably not that mainstream, but it'd
be very nice. Is there any chance of having support for this behavior?
I don't know anything about the underlying mechanism for supporting
interface extension, so I don't know if what I'm asking is trivial or not.
Thanks,
Hans
At 07:55 16/02/2004, Hans Lellelid wrote:
I have a need in a current application to extend interfaces and possibly
re-define (change signature) some of the inherited methods in the child
interface.e.g.
interface Foo {
public function __construct(MyCls $var);
public function myFunction();
}interface Bar extends Foo {
public function __construct(MyCls $var, $var2 = null);
public function myOtherFunction();
}class A implements Bar {
public function __construct(MyCls $var, $var2 = null) {
// ...
}
public function myFunction() {
// ...
}
public function myOtherFunction() {
// ...
}
}This is not currently possible in PHP5b4, due to the (new?) "Can't inherit
abstract function" errors generated by the engine. I.e. if I try to
redefine __construct() I will get an error.The need for this capability is probably not that mainstream, but it'd be
very nice. Is there any chance of having support for this behavior? I
don't know anything about the underlying mechanism for supporting
interface extension, so I don't know if what I'm asking is trivial or not.
You're not supposed to change the signature when you're
extending/implementing interfaces. I'll try to see if it's feasible to
improve the checks so that they compare signatures in a smarter way (i.e.,
func($arg1, $arg2=null) is compatible with func($arg1), and currently it's
not detected that way).
Zeev
Hi -
Zeev Suraski wrote:
At 07:55 16/02/2004, Hans Lellelid wrote:
I have a need in a current application to extend interfaces and
possibly re-define (change signature) some of the inherited methods in
the child interface.
...You're not supposed to change the signature when you're
extending/implementing interfaces. I'll try to see if it's feasible to
improve the checks so that they compare signatures in a smarter way
(i.e., func($arg1, $arg2=null) is compatible with func($arg1), and
currently it's not detected that way).
Yeah, I realize that wanting to change signatures of parent interfaces
is a little weird; I'd submit that it does allow for some nice design
possibilities -- but perhaps modifying an interface is at odds with the
idea of an interface. I think I probably want to just copy & paste the
methods that are the same rather than extend.
Making it possible to re-define methods w/ additional null params would
be nice if that makes sense.
Thanks!
Hans
Hello Hans,
Monday, February 16, 2004, 10:07:53 PM, you wrote:
Hi -
Zeev Suraski wrote:
At 07:55 16/02/2004, Hans Lellelid wrote:
I have a need in a current application to extend interfaces and
possibly re-define (change signature) some of the inherited methods in
the child interface.
...You're not supposed to change the signature when you're
extending/implementing interfaces. I'll try to see if it's feasible to
improve the checks so that they compare signatures in a smarter way
(i.e., func($arg1, $arg2=null) is compatible with func($arg1), and
currently it's not detected that way).
Yeah, I realize that wanting to change signatures of parent interfaces
is a little weird; I'd submit that it does allow for some nice design
possibilities -- but perhaps modifying an interface is at odds with the
idea of an interface. I think I probably want to just copy & paste the
methods that are the same rather than extend.
Making it possible to re-define methods w/ additional null params would
be nice if that makes sense.
In C++ overwritten default value of derived classes are ignored because the
binding happens at compile time and the default values would have been
evaluated at run time to work as expected.
Now PHP is different. We would have the default values at runtim and compile
time and the problem is only inheriting the methods. Currently NULL
matches
any time so it could work. Zeev maybe this is something worth to verify?
Best regards,
Marcus mailto:helly@php.net
Hi -
This issue of inheritance & interfaces persists to give me problems...
Perhaps I'm going about this wrong for PHP.
Zeev Suraski wrote:
You're not supposed to change the signature when you're
extending/implementing interfaces. I'll try to see if it's feasible
to improve the checks so that they compare signatures in a smarter way
(i.e., func($arg1, $arg2=null) is compatible with func($arg1), and
currently it's not detected that way).
Here's the problem. For background, I'm working on Creole, a JDBC-like
DB abstraction API for PHP. This framework has both Statement and
PreparedStatement classes. Originally I was using an abstract class
model that I'm now moving to interfaces for added flexibility (ability
to swap in decorator classes, etc.). I'm having a difficult time
representing the relationship between these classes when using interfaces.
The interfaces and class definitions are as follows:
interface Statement {
// methods
}
interface PreparedStatement {
// methods, including some identical to Statement & some w/ same name
// but different signature
}
class SQLiteStatement implements Statement {
// impl
}
class SQLitePreparedStatement extends SQLiteStatement implements
PreparedStatement {
// impl
}
Originally, the PreparedStatement interface was extending the Statement
interface, but this broke because several PreparedStatement methods have
different signatures from their Statement counterparts -- hence my
interest in allowing interfaces to re-define signatures. Now I am no
longer using inheritance for the interfaces, but the problem now is
that in SQLitePreparedStatement I am unable to inherit methods from
SQLiteStatement that meet the interface requirements of PreparedStatement.
E.g. -- both SQLiteStatement and SQLitePreparedStatement have identical
setLimit() and setOffset() methods. I'd like to be able to inherit
these from SQLiteStatement -- indeed there's a lot of code that's the
same. I also need these methods to be specified in the
PreparedStatement interface (since I can no longer using inheritance for
that, I have to redefine these methods in PreparedStatement).
I just get this when I try to inherit these functions:
Fatal error: Can't inherit abstract function
PreparedStatement::setLimit() (previously declared abstract in
Statement) in
/home/sandbox/creole2/classes/creole/drivers/sqlite/SQLitePreparedStatement.php
on line 32
Any chance that the engine could be modified to allow inherited methods
to meet interface requirements? (Again, extending the interfaces is not
an option since some method signatures change & PHP won't allow this.)
The only option I see currently is to duplicate all methods from
SQLiteStatment in SQLitePreparedStatement, which will produce the
correct end results but with a definite readability/maintainability
price. To me the bottom line is that these classes are definitely
related and that it's frustrating not to be able to express that in PHP.
Perhaps there's a workaround that's just not occurring to me right now...?
Thanks again!
Hans