关于php:oop接口点

OOP the point of interface

本问题已经有最佳答案,请猛点这里访问。

Possible Duplicate:
Interface vs Abstract Class (general OO)

编辑:我刚刚读了"可能的重复"中的问题和答案,我真的很难过有人认为这两个问题甚至相似…但是,哦…

——————————————————————————————————————————————————————————————————————————————————————————————————————————————--

大家好,我试图理解OOP范式中的接口。我知道抽象类和接口之间的区别,我也知道接口基本上允许简单的多重继承行为和设计,但我没有得到的是"承诺原则"。我的意思是,接口应该是实现接口的类实现了所有接口方法的承诺。

我不明白的是,每次调用InstanceOf的方法时,我们是否需要检查类是否实现了与InstanceOf的接口?如果不阅读文档,您就不知道某些类实现了接口。如果你读到的代码比你自己看到的还要多,你可以定义这个方法并调用它吗?!

如果我有

A.案

1
2
3
class Ball{
function kick(){...};
}

或案例B

1
2
3
4
5
6
7
interface Kickable{
function kick;
}

class Ball implements Kickable{
function kick(){...};
}

唯一的区别是,如果a调用一个不存在的方法("在运行时"),我会得到一个错误;如果b调用一个不存在的方法,我会得到这个错误,当试图"编译"代码时,我会得到这个错误。运行时和编译在这里使用肯定是错误的(PHP环境)。

我记得在Java中有一个可运行的接口,可以实现线程化。为什么我们必须实现一个可运行的接口,然后在该类中定义run()方法?我的意思是,类可以有一个不实现接口的运行方法,并且有方法检查类是否定义了一个特殊的方法。好吧,也许我的Java部分问题有点混淆:)

我很抱歉这个令人困惑的问题,但我希望有人能理解这些问题,现在他可以分享他的结论了:)

谢谢,卢卡


您已经列出了所讨论的接口的大部分优点,即:

  • 它们允许多个(接口)继承

您还提到您知道抽象类和接口之间的区别。其中还有使用接口的另一个好处:

  • 任何类都可以实现接口,而不是任何类都可以从抽象类派生

这基本上是对上面第一点的重新散列,但是它将它放在了一个您以前可能没有考虑过的透视图中。举一个Java可运行的例子:如果RunnEnable是一个抽象类,那么实现线程的任何一个类都需要从它继承。这最终会导致代码极不灵活,因为您无法从任何其他基类继承代码。但是,由于runnable是一个接口,所以可以让任何类实现它(不管它可能从哪个基类继承)。

我理解您对必须检查类是否实现接口的关注——不幸的是,在弱类型语言中,您必须这样做,特别是由于php类型暗示还没有完全形成自己的语言。

在强类型语言(如Java)中,通常没有这样的顾虑,因为如果在不实现接口(或不实现特定方法)的类上调用接口方法,则会导致编译时错误。


不,您不必使用InstanceOf。用于运行时类型检查。如果要确保使用的是实现该接口的类,只需将接口类型放入方法签名中即可。例如

1
2
3
4
5
6
7
8
9
10
11
public interface yourInterface{
      public void foo();
}

public class yourClass implements yourInterface{
     public void foo(){} //you need to implement this method, otherwise it won't compile
}

public class anotherClass{
     public void bar(yourInterface object){} //you can pass any object to"bar" method if the object implements yourInterface. yourClass object will be fine
}

那么你还可以做些其他的好事,这取决于你的语言。例如,用Java可以强制泛型类型实现给定的接口,允许泛型编程:

1
2
3
class generiClass<T extends yourInterface>{
      public void genericMethod(T object){} //you can use a generic T class, but T needs to implement yourInterface
}

接口的原因主要有2个:

  • 强制类实现某些方法
  • 允许多个继承类语言中没有多继承的语言(如C++语言,其中有多个继承,不需要接口)。或者说得更好,接口与纯抽象类是完全相同的)

  • "I also know that interfaces basically allow easy multiple inheritance behaviour and design"

    我想你误解了那部分。接口允许您确保特定类具有一组属性/方法。

    例子:

    1
    2
    3
    function foo($obj) {
      $obj->bar(); // fails with foo(array());
    }

    VS:

    1
    2
    3
    4
    5
    6
    7
    interface foobar {
      function bar();
    }

    function foo(foobar $obj) { // $obj *must* have a bar() method
      $obj->bar();
    }