Real world example. Say I have a DB library. The library relies on depenendency injection to 'inject' the required driver (provider/implementation) whether it be mysql, mssql or sqlite.
Code: Select all
$db = new Database(new MySQLProvider('localhost', 'user', 'pass'));1. Inherit from an abstract class
2. Implement an interface
Or both they are not mutually exclusive.
As a DB library author I might define an interface which all 'providers' must implement:
Code: Select all
interface Provider{
function insert($table, $params);
function update($table, $id_primary, $params);
function delete($table, $id_primary);
function select($table, $fields);
}So while an interface is a contract, it's not a very strict contract, especially in PHP.
An abstract class on the other hand, is like an interface but it CAN offer some basic functionality which is common to all derived classes. Drawing on the example above.
The implementation of the various providers classes (MySQL, MSSQL, SQLite) might have common functionality which can be reused by all or most providers. Perhaps functionality INSERT, UPDATE and DELETE could be implemented in a abstract class, only because the SQL for every provider for those three operations are identical (I think just an example here).
However each provider class would need to implement (override at least) the SELECT method because that SQL is different across databases.
So an abstract class can save you a lot of work as the example above should tell you, however it's easier said than done. It's usually not worth using abstract classes unless you really have proven functionality to be common. If it applies to 2 providers and NOT 3 or 4 more, then an abstract class is not the right solution for code reuse. Using a composite would make more sense.
Cheers,
Alex