接口作为Java中的方法参数
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/2575429/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
interface as a method parameter in Java
提问by zihaoyu
I had an interview days ago and was thrown a question like this.
几天前我接受了一次采访,被抛出了这样的问题。
Q: Reverse a linked list. Following code is given:
问:反转链表。给出以下代码:
public class ReverseList {
interface NodeList {
int getItem();
NodeList nextNode();
}
void reverse(NodeList node) {
}
public static void main(String[] args) {
}
}
I was confused because I did not know an interface object could be used as a method parameter. The interviewer explained a little bit but I am still not sure about this. Could somebody enlighten me?
我很困惑,因为我不知道接口对象可以用作方法参数。面试官解释了一点,但我仍然不确定这一点。有人可以启发我吗?
采纳答案by Michael Borgwardt
This is in fact one of the most common and useful ways to use an interface. The interface defines a contract, and your code can work with any class that implements the interface, without having to know the concrete class - it can even work with classes that didn't exist yet when the code was written.
这实际上是使用接口的最常见和最有用的方法之一。接口定义了一个契约,您的代码可以与任何实现该接口的类一起工作,而无需知道具体的类——它甚至可以与编写代码时还不存在的类一起工作。
There are many examples in the Java standard API, especially in the collections framework. For example, Collections.sort()can sort anything that implements the List
interface (not just ArrayList
or LinkedList
, though implementing your own List
is uncommon) and whose contents implement the Comparable
interface (not just String
or the numerical wrapper classes - and having your own class implement Comparable
for that purpose is quitecommon).
Java 标准 API 中有很多示例,尤其是在集合框架中。例如,Collections.sort()可以排序任何实现的List
接口(不只是ArrayList
或者LinkedList
,虽然实现自己的List
不常见),其内容实现Comparable
接口(不只是String
或数值包装类-和拥有自己的类实现Comparable
为目的很常见)。
回答by Pindatjuh
The argument needs an object, which class implements an interface (the parameter).
参数需要一个对象,该类实现了一个接口(参数)。
In pseudoJava the code:
在伪Java中的代码:
void reverse(NodeList node) {
// your code
}
is equal to:
等于:
reverse(x) {
if(x == null || x instanceof NodeList) {
// your code
}else throw new RuntimeException("Some sort of error.");
}
Note; read more on Interfaces here: http://java.sun.com/docs/books/tutorial/java/IandI/interfaceAsType.html
笔记; 在此处阅读有关接口的更多信息:http: //java.sun.com/docs/books/tutorial/java/IandI/interfaceAsType.html
回答by Ben Zotto
It's not the interface "object" being passed to the method, still just a regular object. It's just a way of saying "this parameter will accept any object that supports this interface". It's equivalent to accepting some object of a base class type, even if you're passing in a subclass.
它不是传递给方法的接口“对象”,仍然只是一个常规对象。这只是一种说法“此参数将接受任何支持此接口的对象”。这相当于接受某个基类类型的对象,即使您传入的是子类。
回答by ahe
This is called programming to interfaces. You don't code to a specific implementation class of node lists but to the interface implemented by all those implementations.
这称为接口编程。您不编码到节点列表的特定实现类,而是编码到所有这些实现实现的接口。
That way your code will still work if someone writes a new and much better implementation of NodeList
after you wrote your reverse method and you don't have to adapt your code for each new implementation of NodeList
.
这样,如果有人NodeList
在您编写了反向方法之后编写了一个新的更好的NodeList
.
回答by Nirmal
The major benefit of using interfaces, IMHO, is being able to test easily. Suppose you have an interface called, PatientManager.
恕我直言,使用接口的主要好处是能够轻松测试。假设您有一个名为 PatientManager 的接口。
You can write specific unit tests for imaginable things like "CachingPatientManager" or "LDAPPatientManager", the use case could be myriad.
您可以为诸如“CachingPatientManager”或“LDAPPatientManager”之类的可以想象的事物编写特定的单元测试,用例可能是无数的。
The benefit is because the programming to interface becomes highly reusable and testable.
好处是因为接口编程变得高度可重用和可测试。
回答by user4660857
You cannot create an instance (/object ) of an Interface. Yes, you can pass Interface as a parameter in the function. But the question seems incomplete. Interface isn't implemented by any class. Something is missing. If you try to run this, compiler will not show any error.
您不能创建接口的实例 (/object)。是的,您可以将接口作为函数中的参数传递。但问题似乎不完整。任何类都没有实现接口。缺了点什么。如果您尝试运行它,编译器将不会显示任何错误。
But, in the reverse() method you need to create an instance of class that implements NodeList interface. I hope this makes sense.
但是,在 reverse() 方法中,您需要创建一个实现 NodeList 接口的类的实例。我希望这是有道理的。
回答by jrook
This is one possible implementation:
这是一种可能的实现:
public class ReverseList {
interface NodeList {
int getItem();
NodeList nextNode();
}
static class Node implements NodeList {
private int item;
private Node next;
@Override
public int getItem() {
return item;
}
public void setItem(int si) {
item = si;
}
@Override
public NodeList nextNode() {
return this.next;
}
public void setNext(Node n) {this.next=n;}
}
Node reverse(NodeList head) {
Node node = (Node) head;
Node previous = null;
while(node.nextNode() !=null) {
Node tempNext = (Node) node.nextNode();
node.setNext(previous);
previous = node;
node = tempNext;
}
node.setNext(previous);
return node;
}
public static void main(String[] args) {
//Initialization block
ReverseList rl = new ReverseList();
Node n1= new Node(); n1.setItem(1);
Node n2=new Node(); n2.setItem(2);
Node n3 =new Node(); n3.setItem(3);
n1.setNext(n2); n2.setNext(n3); n3.setNext(null);
//Reversing the list
System.out.println("Before reversal");
System.out.println(n1.getItem() +"->"
+ n1.nextNode().getItem() + "->"
+ n1.nextNode().nextNode().getItem() + "->"
+n1.nextNode().nextNode().nextNode());
rl.reverse(n1);
System.out.println("\nAfter reversal");
System.out.println(n3.getItem() +"->"
+ n3.nextNode().getItem() + "->"
+ n3.nextNode().nextNode().getItem() + "->"
+n3.nextNode().nextNode().nextNode());
}
}
Program output:
程序输出:
Before reversal
1->2->3->null
After reversal
3->2->1->null
I am very curious to know if this problem can be solved by using an anonymous class. Any ideas?
我很想知道这个问题是否可以通过使用匿名类来解决。有任何想法吗?
回答by Yoho
Had this same confusion while learning lambda stuff. This video didnt explain the concept, but it's a clear way for you to see how it works in terms of passing an interface as a parameter.
在学习 lambda 的东西时也有同样的困惑。这个视频没有解释这个概念,但它是一种清晰的方式,让您了解它在将接口作为参数传递方面是如何工作的。