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:49

Interfaces are like your genes.

Abstract classes are like your actual parents.

Their purposes are hereditary, but in the case of abstract classes vs interfaces, what is inherited is more specific.

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

We saw that abstract classes and interfaces are similar in that they provide abstract methods that must be implemented in the child classes. However, they still have the following differences:

1.Interfaces can include abstract methods and constants, but cannot contain concrete methods and variables.

2.All the methods in the interface must be in the public visibility scope.

3.A class can implement more than one interface, while it can inherit from only one abstract class.

                                  interface                      abstract class
the code                     - abstract methods               - abstract methods
                             - constants                      - constants                  
                                                              - concrete methods
                                                              - concrete variables

access modifiers             
                             - public                         - public
                                                              - protected
                                                              - private
                                                                etc.
number of parents          The same class can implement
                           more than 1 interface              The child class can 
                                                              inherit only from 1 abstract class

Hope this will helps to anyone to understand!

查看更多
时光乱了年华
4楼-- · 2019-01-01 14:53

In my opinion, interfaces should be preferred over non-functional abstract classes. I wouldn't be surprised if there would be even a performance hit there, as there is only one object instantiated, instead of parsing two, combining them (although, I can't be sure, I'm not familiar with the inner workings of OOP PHP).

It is true that interfaces are less useful/meaningful than compared to, say, Java. On the other hand, PHP6 will introduce even more type hinting, including type hinting for return values. This should add some value to PHP interfaces.

tl;dr: interfaces defines a list of methods that need to be followed (think API), while an abstract class gives some basic/common functionality, which the subclasses refine to specific needs.

查看更多
素衣白纱
5楼-- · 2019-01-01 14:55

Interfaces are essentially a blueprint for what you can create. They define what methods a class must have, but you can create extra methods outside of those limitations.

I'm not sure what you mean by not being able to add code to methods - because you can. Are you applying the interface to an abstract class or the class that extends it?

A method in the interface applied to the abstract class will need to be implemented in that abstract class. However apply that interface to the extending class and the method only needs implementing in the extending class. I could be wrong here - I don't use interfaces as often as I could/should.

I've always thought of interfaces as a pattern for external developers or an extra ruleset to ensure things are correct.

查看更多
旧时光的记忆
6楼-- · 2019-01-01 14:57

Why would you need an interface, if there are already abstract classes? To prevent multiple inheritance (can cause multiple known problems).

One of such problems:

The "diamond problem" (sometimes referred to as the "deadly diamond of death") is an ambiguity that arises when two classes B and C inherit from A and class D inherits from both B and C. If there is a method in A that B and C have overridden, and D does not override it, then which version of the method does D inherit: that of B, or that of C?

Source: https://en.wikipedia.org/wiki/Multiple_inheritance#The_diamond_problem

Why/When to use an interface? An example... All cars in the world have the same interface (methods)... AccelerationPedalIsOnTheRight(), BrakePedalISOnTheLeft(). Imagine that each car brand would have these "methods" different from another brand. BMW would have The brakes on the right side, and Honda would have brakes on the left side of the wheel. People would have to learn how these "methods" work every time they would buy a different brand of car. That's why it's a good idea to have the same interface in multiple "places."

What does an interface do for you (why would someone even use one)? An interface prevents you from making "mistakes" (it assures you that all classes which implement a specific interface, will all have the methods which are in the interface).

// Methods inside this interface must be implemented in all classes which implement this interface.
interface IPersonService
{   
    public function Create($personObject);
}

class MySqlPerson implements IPersonService
{
    public function Create($personObject)
    {
        // Create a new person in MySql database.
    }
}

class MongoPerson implements IPersonService
{
    public function Create($personObject)
    {
        // Mongo database creates a new person differently then MySQL does. But the code outside of this method doesn't care how a person will be added to the database, all it has to know is that the method Create() has 1 parameter (the person object).
    }
}

This way, the Create() method will always be used the same way. It doesn't matter if we are using the MySqlPerson class or the MongoPerson class. The way how we are using a method stays the same (the interface stays the same).

For example, it will be used like this (everywhere in our code):

new MySqlPerson()->Create($personObject);
new MongoPerson()->Create($personObject);

This way, something like this can't happen:

new MySqlPerson()->Create($personObject)
new MongoPerson()->Create($personsName, $personsAge);

It's much easier to remember one interface and use the same one everywhere, than multiple different ones.

This way, the inside of the Create() method can be different for different classes, without affecting the "outside" code, which calls this method. All the outside code has to know is that the method Create() has 1 parameter ($personObject), because that's how the outside code will use/call the method. The outside code doesn't care what's happening inside the method; it only has to know how to use/call it.

You can do this without an interface as well, but if you use an interface, it's "safer" (because it prevents you to make mistakes). The interface assures you that the method Create() will have the same signature (same types and a same number of parameters) in all classes that implement the interface. This way you can be sure that ANY class which implements the IPersonService interface, will have the method Create() (in this example) and will need only 1 parameter ($personObject) to get called/used.

A class that implements an interface must implement all methods, which the interface does/has.

I hope that I didn't repeat myself too much.

查看更多
临风纵饮
7楼-- · 2019-01-01 14:58

I can't remember if PHP is different in this respect, but in Java, you can implement multiple Interfaces, but you can't inherit multiple abstract classes. I'd assume PHP works the same way.

In PHP you can apply multiple interfaces by seperating them with a comma (I think, I don't find that a clean soloution).

As for multiple abstract classes you could have multiple abstracts extending each other (again, I'm not totally sure about that but I think I've seen that somewhere before). The only thing you can't extend is a final class.

查看更多
登录 后发表回答