解释PHP接口

时间:2014-10-18 07:30:34

标签: php data-structures

您能为我帮助澄清PHP界面吗?我明白了主要观点是多个类可以实现一些相同的功能。

abstract class Plane {
     public function openDoors();
}


interface Fliers {
     public function fly();
}

现在让我们使用它们

class Boeing747 extends Plane implements Fliers {
  public function fly() {
     // some stuff
  }

  public function openDoors() {
    // do something
  }

}

class Tweety implements Fliers{
    public function fly() {
    // some stuff
    }
}

在这种情况下,Boeing747和Tweety都可以实现接口Fliers来访问公共函数fly()。但是,在我看到的所有示例中,接口中实际上没有定义任何功能,而是在类方法本身内部调用它时。

为什么我不会在每个Boeing747和Tweety中将fly()定义为单独的函数,而不是使用接口?你能提供一个有利的具体基本例子吗?谢谢!

2 个答案:

答案 0 :(得分:3)

这是一种称为Design by Contract的技术。本质上,接口用作契约,或承诺任何实现接口的类都将展示一组特定的行为。它允许您的代码检查传递给它的对象的功能,而不必担心在当前上下文中无关紧要的细节。例如,你的openDoors()方法可以同样适用于房屋,飞机,运河锁,汽车或任何其他带门的东西,但除了门外,所有这些东西都没有什么共同之处。即使他们都支持可以打开门的想法,他们实际上可能以完全不同的方式执行开门动作。

界面允许您告诉调用代码,所有这些东西都有可以打开的门,而不必在它们之间不存在任何人为关系。 instanceof关键字允许您检查对象是否满足特定条件(如果它是特定类或子类的实例,或者它是否实现特定接口)。

interface ThingWithDoors {
    public function openDoors ();
}

class House implements ThingWithDoors {
    // Implement openDoors here
}

class CanalLock implements ThingWithDoors {
    // Implement openDoors here
}

class Boeing747 extends Aircraft implements ThingWithDoors {
    // Implement openDoors here
}

// Calling code

if ($object instanceof ThingWithDoors) {
    // We don't know exactly what class we have, but we do know it has an openDoors method
    $object -> openDoors ();
}

理论上你可以用其他PHP功能实现同样的东西,比如method_exists或Reflection,但是这些技术远非理想,因为没有任何合同可以强制执行任何东西(两个不同的类可以实现开门但是有完全不同的名称执行此操作的方法,您必须使用method_exists调用检查两者。然后,假设某些其他程序员在系统中添加了一个新类,它以与您已经检查过的方式完全不同的方式实现门打开。在整个程序中可以打开门的所有代码都必须更新以考虑这种新方法!但是,如果向系统添加一个新类并且它实现了ThingWithDoors接口,那么打开门的所有代码将自动使用新类,就像它对旧类一样,而不进行任何修改(前提是新类实现)接口正确并尊重返回值,遗憾的是,PHP接口不强制执行这些值。

程序员的另一个好处是,他们不必继续查阅文档/源代码中如何调用对象中的某些行为。如果他们知道ThingWithDoors界面是什么样的,那么他们知道实现ThingWithDoors的所有东西都可以打开它的门,并且执行它的方法调用总是openDoors()。这可以为您节省相当多的时间作为开发人员,尤其是在一个大项目上!

答案 1 :(得分:0)

在OO PHP中,一个对象只能有一个父类。要了解为何采用此方法,请使用 Bird类来显示多重继承以及它如何导致问题。

如果你想创建一个 Wooping_Crane类,从Bird类派生这个类是有意义的。假设您还有 Endangered_Species类

多重继承允许您从这两个类(Bird和Endangered类)的组合中创建Wooping_Crane类。在您意识到两个类都定义了饮食行为之前,这似乎是一个很好的主意。哪一个更喜欢?所以这是多重继承的缺点。

PHP以两种方式解决了这个问题:首先,使用接口 - 只有函数定义的类。

如果Endangered_Species是一个界面而不是一个类,拥有一个以上的饮食功能并不重要。 Bird类中的方法定义将充当接口函数的实现。通过这种方式,接口避免了两次定义相同功能的问题。

其次,使用特征。你可以在其他帖子中阅读它。