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

--
PHP Internals - PHP Runtime Development Mailing List
To unsubscribe, visit: http://www.php.net/unsub.php



Reply via email to