修改 我只是阅读了“可能重复”的问题和答案,我觉得很难过,有人认为这两个问题甚至相似......但是,哦,好吧......
-------------------------------------------- -----------------------------
大家好, 我试图了解OOP范例中的接口。 我知道抽象类和接口之间的区别,我也知道接口基本上允许简单的多继承行为和设计,但我没有得到的是“承诺原则”。我的意思是,接口应该是实现接口的类实现所有接口方法的承诺。
我不明白的是,每次调用其方法时,我们是否必须检查类是否实现了与instanceOf的接口?没有阅读文档,你不知道一些类实现接口。如果您阅读代码而不是您可以看到自己已经定义了该方法,您可以调用它吗?!
如果我有
案例A。
class Ball{
function kick(){...};
}
或 案例B。
interface Kickable{
function kick;
}
class Ball implements Kickable{
function kick(){...};
}
唯一的区别是,在A情况下我会在调用一个不存在的方法时遇到错误(“在运行时”),如果是B,我会在尝试运行代码时遇到此错误试图“编译”。运行时和编译肯定在这里使用错误(PHP环境)。
我记得在Java中有一个Runnable接口可以启用线程。为什么我们必须实现一个Runnable接口,然后在该类中定义run()方法?我的意思是,类可以有一个没有实现接口的Run方法,并且有办法检查类是否定义了特殊方法。好吧,也许我的Java部分问题有点令人困惑:)))
我很抱歉这个令人困惑的问题,但我希望有人在理解中遇到这些问题,现在他可以分享他的结论:)
谢谢, 卢卡
答案 0 :(得分:4)
您已经在问题中列出了界面的大部分好处,即:
您还提到您了解抽象类和接口之间的区别。其中有使用接口的另一个好处:
这基本上是上面第一点的重新哈希,但它把它放在你以前可能没有考虑过的视角中。以Java Runnable为例:如果Runnable是一个抽象类,那么实现线程的任何一个类都需要继承它。这将最终导致极其不灵活的代码,因为您无法从任何其他基类继承。但是,由于Runnable是一个接口,您可以让任何类实现它(无论它可以从哪个基类继承)。
我理解你不得不检查一个类是否实现了一个接口 - 不幸的是,在一个弱类型的语言中你必须这样做,特别是因为PHP类型提示还没有完全实现它。
在类似Java的强类型语言中,通常没有这样的问题,因为如果在没有实现接口的类上调用接口方法(或者没有实现接口),则会出现编译时错误实施具体方法)。
答案 1 :(得分:2)
没有。你不必使用instanceof。这是运行时类型检查。 如果要确保使用实现该接口的类,只需将接口类型放在方法签名中即可。例如
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,您可以强制使用泛型类型来实现给定的接口,从而允许泛型编程:
class generiClass<T extends yourInterface>{
public void genericMethod(T object){} //you can use a generic T class, but T needs to implement yourInterface
}
接口的原因主要是2:
答案 2 :(得分:1)
“我也知道接口基本上允许简单的多继承行为和设计”
我认为你误解了这一部分。接口允许您确保特定类具有一组属性/方法。
示例:
function foo($obj) {
$obj->bar(); // fails with foo(array());
}
VS
interface foobar {
function bar();
}
function foo(foobar $obj) { // $obj *must* have a bar() method
$obj->bar();
}