What is the point of interfaces in PHP?

2019-01-01 14:16发布

Interfaces allow you to create code which defines the methods of classes that implement it. You cannot however add any code to those methods.

Abstract classes allow you to do the same thing, along with adding code to the method.

Now if you can achieve the same goal with abstract classes, why do we even need the concept of interfaces?

I've been told that it has to do with OO theory from C++ to Java, which is what PHP's OO stuff is based on. Is the concept useful in Java but not in PHP? Is it just a way to keep from having placeholders littered in the abstract class? Am I missing something?

14条回答
谁念西风独自凉
2楼-- · 2019-01-01 14:42

The concept is useful all around in object oriented programming. To me I think of an interface as a contract. So long my class and your class agree on this method signature contract we can "interface". As for abstract classes those I see as more of base classes that stub out some methods and I need to fill in the details.

查看更多
怪性笑人.
3楼-- · 2019-01-01 14:42

Interfaces exist not as a base on which classes can extend but as a map of required functions.

The following is an example of using an interface where an abstract class does not fit:
Lets say I have a calendar application that allows users to import calendar data from external sources. I would write classes to handle importing each type of data source (ical, rss, atom, json) Each of those classes would implement a common interface that would ensure they all have the common public methods that my application needs to get the data.

<?php

interface ImportableFeed 
{
    public function getEvents();
}

Then when a user adds a new feed I can identify the type of feed it is and use the class developed for that type to import the data. Each class written to import data for a specific feed would have completely different code, there may otherwise be very few similarities between the classes outside of the fact that they are required to implement the interface that allows my application to consume them. If I were to use an abstract class, I could very easily ignore the fact that I have not overridden the getEvents() method which would then break my application in this instance whereas using an interface would not let my app run if ANY of the methods defined in the interface do not exist in the class that implemented it. My app doesn't have to care what class it uses to get data from a feed, only that the methods it needs to get that data are present.

To take this a step further, the interface proves to be extremely useful when I come back to my calendar app with the intent of adding another feed type. Using the ImportableFeed interface means I can continue adding more classes that import different feed types by simply adding new classes that implement this interface. This allows me to add tons of functionality without having to add unnecessarily bulk to my core application since my core application only relies on there being the public methods available that the interface requires so as long as my new feed import classes implement the ImportableFeed interface then I know I can just drop it in place and keep moving.

This is just a very simple start. I can then create another interface that all my calendar classes can be required to implement that offers more functionality specific to the feed type the class handles. Another good example would be a method to verify the feed type, etc.

This goes beyond the question but since I used the example above: Interfaces come with their own set of issues if used in this manner. I find myself needing to ensure the output that is returned from the methods implemented to match the interface and to achieve this I use an IDE that reads PHPDoc blocks and add the return type as a type hint in a PHPDoc block of the interface which will then translate to the concrete class that implements it. My classes that consume the data output from the classes that implement this interface will then at the very least know it's expecting an array returned in this example:

<?php
interface ImportableFeed 
{
    /**
     * @return array
     */
    public function getEvents();
}

There isn't much room in which to compare abstract classes and interfaces. Interfaces are simply maps that when implemented require the class to have a set of public interfaces.

查看更多
爱死公子算了
4楼-- · 2019-01-01 14:42

Interfaces aren't just for making sure developers implement certain methods. The idea is that because these classes are guaranteed to have certain methods, you can use these methods even if you don't know the class's actual type. Example:

interface Readable {
  String read();
}

List<Readable> readables; // dunno what these actually are, but we know they have read();
for(Readable reader : readables)
  System.out.println(reader.read());

In many cases, it doesn't make sense to provide a base class, abstract or not, because the implementations vary wildly and don't share anything in common besides a few methods.

Dynamically typed languages have the notion of "duck-typing" where you don't need interfaces; you are free to assume that the object has the method that you're calling on it. This works around the problem in statically typed languages where your object has some method (in my example, read()), but doesn't implement the interface.

查看更多
何处买醉
5楼-- · 2019-01-01 14:44

The entire point of interfaces is to give you the flexibility to have your class be forced to implement multiple interfaces, but still not allow multiple inheritance. The issues with inheriting from multiple classes are many and varied and the wikipedia page on it sums them up pretty well.

Interfaces are a compromise. Most of the problems with multiple inheritance don't apply to abstract base classes, so most modern languages these days disable multiple inheritance yet call abstract base classes interfaces and allows a class to "implement" as many of those as they want.

查看更多
余生无你
6楼-- · 2019-01-01 14:49

You will use interfaces in PHP:

  1. To hide implementation - establish an access protocol to a class of objects an change the underlying implementation without refactoring in all the places you've used that objects
  2. To check type - as in making sure that a parameter has a specific type $object instanceof MyInterface
  3. To enforce parameter checking at runtime
  4. To implement multiple behaviours into a single class (build complex types)

    class Car implements EngineInterface, BodyInterface, SteeringInterface {

so that a Car object ca now start(), stop() (EngineInterface) or goRight(),goLeft() (Steering interface)

and other things I cannot think of right now

Number 4 it's probably the most obvious use case that you cannot address with abstract classes.

From Thinking in Java:

An interface says, “This is what all classes that implement this particular interface will look like.” Thus, any code that uses a particular interface knows what methods can be called for that interface, and that’s all. So the interface is used to establish a “protocol” between classes.

查看更多
听够珍惜
7楼-- · 2019-01-01 14:49

Below are the points for PHP Interface

  1. It is used to define required no of methods in class [if you want to load html then id and name is required so in this case interface include setID and setName].
  2. Interface strictly force class to include all the methods define in it.
  3. You can only define method in interface with public accessibility.
  4. You can also extend interface like class. You can extend interface in php using extends keyword.
  5. Extend multiple interface.
  6. You can not implement 2 interfaces if both share function with same name. It will throw error.

Example code :

interface test{
    public function A($i);
    public function B($j = 20);
}

class xyz implements test{
    public function A($a){
        echo "CLASS A Value is ".$a;
    }
    public function B($b){
        echo "CLASS B Value is ".$b;
    }
}
$x = new xyz();
echo $x->A(11);
echo "<br/>";
echo $x->B(10);
查看更多
登录 后发表回答