【发布时间】:2014-08-21 09:25:02
【问题描述】:
最近有人向我介绍了 Java 中的接口,但我无法理解它们的用途。所以,假设我有以下内容:
//this is an interface
public interface DanceMoves {
public void theJitterbug(int twists);
public void theHustle(int steps);
public void theMoonwalk(int slides);
}
然后我有一个实现这个接口的类:
public class DanceClub implements DanceMoves {
public void theJitterbug(int twists) {
System.out.println("Twist " + twists + " times!");
}
public void theHustle(int steps) {
System.out.println("Step " + steps + " times!");
}
public void theMoonwalk(int slides) {
System.out.println("Slide " + slides + " times!");
}
//more methods can go here
public static void main(String[] args) {
DanceClub letsDance = new DanceClub();
letsDance.theJitterbug(5);
letsDance.theHustle(4);
letsDance.theMoonwalk(3);
}
}
也许我还有另一个实现这个接口的方法:
public class Diner implements DanceMoves {
public void theJitterbug(int twists) {
System.out.println("Twist " + twists + " times!");
System.out.println("We only do the jitterbug in diners!");
}
public void theHustle(int steps) {
}
public void theMoonwalk(int slides) {
}
public static void main(String[] args) {
Diner letsDanceAgain = new Diner();
letsDanceAgain.theJitterbug(5);
}
}
所以我的问题是,如果我们必须重写所有接口方法,为什么还要费心去实现一个接口呢?这是如何复用代码的?
编辑:非常感谢所有回答的人!我是 Java 新手,到目前为止我学过的唯一其他语言是 Jython。因此,虽然很多概念翻译得很好,但一些较新的东西对我来说有点难以理解。
我也很欣赏下面给出的响应示例,以及指向先前问题和外部资源的链接。实际上,我之前已经阅读了大部分这些问题,并且也去过那些外部资源,但在我能够更清楚地了解我实际阅读的内容后,它们会更有帮助!
但无论如何!我真正想做的是写下我对接口的重要收获(为了我和后代的利益),看看我是否真的“明白”了。我之前的问题是,如果我们必须重写所有接口方法,为什么还要费心去实现接口呢?如何重用代码?。使用 Elliot Frisch 对我的示例的修改:
public interface Dance { //an interface
public void boogie(int count);
}
现在,您可以拥有实现此接口的相关或非相关方法 -
public class theMoonwalk implements Dance {
public void boogie(int count) {
System.out.println("Slide " + count + " times!");
}
public void mJ() {
System.out.println("Michael Jackson did this dance!");
}
public class theHustle implements Dance {
public void boogie(int steps) {
System.out.println("Step " + steps + " times!");
}
}
public class theJitterBug implements Dance {
public void boogie(int twists) {
System.out.println("Twist " + twists + " times!");
}
}
public class crazyUncle implements Dance {
public void boogie(int shimmy) {
System.out.println("I really don't know how to dance.");
}
public void yap() {
System.out.println("When I was your age...!");
}
}
然后使用它,
public static void main(String[] args) {
Dance[] dances = new Dance[] {
new theHustle(), new theMoonwalk(), new theJitterBug(), new crazyUncle()
};
for (Dance d : dances) { //for each element in this array of type Dance...
// Note: The caller just boogies. The object determines the "move".
d.boogie(3);
}
}
现在,如果我必须重写所有接口方法,为什么我应该费心实现接口,这是我的解释:
因为 theHustle、theMoonwalk、theJitterbug 和 crazyUncle 类都实现了 Dance 接口,所以它们实际上“签署”了一份“合同”,保证这些类的实例至少包含来自舞蹈界面。 因此,即使 theMoonwalk 类与 crazyUncle 类不同,例如 theMoonwalk 对象和 crazyUncle 对象也可以包含在 Dance 类型的数组中,因为这些对象包含 Dance 接口的“DNA”。
此外,我可以在不同的类中有另一个方法,该方法接受 Dance 类型的参数:
public void danceExercise(Dance d, int num) {
d.boogie(num);
}
在调用 danceExercise 方法时,对于 Dance d 参数,我可以提供任何实现了 Dance 接口的类型的值。因此,由于 crazyUncle 和 theMoonwalk 都实现了 Dance,我可以提供一个 crazyUncle 的实例或一个期望有 Dance 的 theMoonwalk 的实例。
TL;DR 谢谢大家!我现在对接口有了更深刻的理解。
【问题讨论】:
-
This 答案可能很有启发性。接口不是(直接)用于代码重用。它们适用于不同的行为。
-
特定问题与 Java 无关。请大致研究 OOP 中的“接口”概念。