为什么需要接口,如果已经有抽象类了呢?
为了防止多重继承(可能会引起多种已知问题)。
其中一种问题:
“菱形问题”(有时称为“致命的死亡之菱形”)是一个模糊性,当两个类B和C从A继承,并且类D从B和C都继承时会出现。如果A中存在一个B和C覆盖的方法,并且D没有覆盖它,则D继承哪个版本的方法:B的版本还是C的版本?
来源:https://en.wikipedia.org/wiki/Multiple_inheritance#The_diamond_problem
为什么/何时使用接口?
例如...全世界所有的汽车都有相同的接口(方法)...加速踏板在右边(),刹车踏板在左边()。想象一下,如果每个品牌的汽车都将这些“方法”与另一个品牌不同。宝马的刹车在方向盘右侧,而本田的刹车在方向盘左侧。人们每次购买不同品牌的汽车时都必须学习这些“方法”。这就是为什么在多个“地方”使用相同的接口是个好主意。
接口对你有什么作用(为什么有人会使用它)?
接口防止你犯“错误”(它确保实现特定接口的所有类都具有接口中的方法)。
// 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).
}
}
这样,Create() 方法将始终以相同的方式使用。无论我们使用 MySqlPerson 类还是 MongoPerson 类,使用方法都保持不变(接口保持不变)。例如,在我们的代码中,它将像这样使用:
new MySqlPerson()->Create($personObject);
new MongoPerson()->Create($personObject);
这样,就不会发生类似这样的情况:
new MySqlPerson()->Create($personObject)
new MongoPerson()->Create($personsName, $personsAge);
记住一个接口并在所有地方使用相同的接口要比记忆多个不同的接口容易得多。
这样,Create() 方法的内部可以因不同的类而异,而不影响调用此方法的“外部”代码。所有外部代码只需要知道该方法 Create() 具有 1 个参数($personObject),因为外部代码将如何使用/调用该方法。外部代码不关心方法内部发生了什么;它只需要知道如何使用/调用它。
您也可以不使用接口来实现此目的,但如果使用接口,则更加“安全”(因为它可以防止出错)。接口确保实现接口的所有类中的方法 Create() 签名相同(具有相同类型和相同数量的参数)。这样,您可以确定实现 IPersonService 接口的任何类都将具有该方法 Create()(在此示例中),并且仅需要 1 个参数($personObject)即可被调用/使用。
实现接口的类必须实现接口所具有的所有方法。
希望我没有重复太多。