I've read these questions:
- Understanding "programming to an interface"
- What is the point of an interface?
- Does it always make sense to "program to an interface" in Java?
I don't understand how to "program to an interface" if you are using methods in concrete classes that aren't part of the interface.
I realize the most common example of this design principle is the List
vs ArrayList
in Java because it is easy to understand and illustrate the point.
Here is a somewhat silly example to illustrate what my question is asking (the code is in PHP but it applies to most OOP languages):
interface ResponseInterface {
public function getStatusCode();
}
class Response implements ResponseInterface {
private $status;
public function getStatusCode() {
return $this->status;
}
}
class AwesomeResponse implements ResponseInterface {
private $status;
private $message = ['200' => 'OK', '500' => 'Internal Server Error'];
public function getStatusCode() {
return $this->status;
}
public function getStatusMessage() {
return $this->message[$status];
}
}
class Server {
public function sendResponse(ResponseInterface $response) {
// this seems wrong -----^
header(vsprintf('HTTP/1.1 %d %s', [
$response->getStatusCode(),
$response->getStatusMessage()
]), true, $response->getStatusCode());
}
}
As you can see, the sendResponse
method takes a ResponseInterface
parameter but it calls getStatusMessage()
which isn't part of the interface but only something implemented in AwesomeResponse
, which implements ResponseInterface
.
The application crashes at runtime when a Response
object is passed as it tries to call the non-existent method getStatusMessage()
. Therefore, the proper implementation would be:
public function sendResponse(AwesomeResponse $response) {
// ...stuff
}
But AwesomeResponse
isn't an interface so how do I program to an interface?
RandomAccessList
interface that is a subinterface ofList
andRandomAccess
and contains signatures of the methods onArrayList
that are not on any interface.ResponseInterface
, andResponseInterface
has no status messages, then there is no such thing as a status message as far as you are concerned.getStatusMessage
toResponseInterface
, or to stop pretending that your code works with any object that implementsResponseInterface
(i.e. stop "programming to that interface"))