interface作为Java中的方法参数

时间:2010-04-04 18:21:43

标签: java oop interface

几天前我接受了一次采访,并提出了这样一个问题。

问:反转链表。下面的代码给出了:

public class ReverseList { 
    interface NodeList {
        int getItem();
        NodeList nextNode();
    }
    void reverse(NodeList node) {

    }
    public static void main(String[] args) {

    }
}

我很困惑,因为我不知道接口对象可以用作方法参数。面试官解释了一下,但我仍然不确定。有人可以启发我吗?

8 个答案:

答案 0 :(得分:57)

这实际上是使用界面最常用和最有用的方法之一。接口定义了一个契约,你的代码可以与任何实现接口的类一起工作,而不必知道具体的类 - 它甚至可以用于编写代码时尚不存在的类。

Java标准API中有许多示例,尤其是在集合框架中。例如,Collections.sort()可以对实现List接口的任何内容进行排序(不只是ArrayListLinkedList,尽管实现您自己的List并不常见)且其内容实现Comparable接口(不仅仅是String或数字包装类 - 并且为此目的拥有自己的类实现Comparable 相当通用)。

答案 1 :(得分:24)

这不是传递给方法的接口“对象”,仍然只是一个常规对象。这只是一种说法“此参数将接受支持此接口的任何对象”。它等同于接受基类类型的某个对象,即使你传入一个子类。

答案 2 :(得分:8)

这称为接口编程。您不需要编写特定的节点列表实现类,而是编写所有这些实现所实现的接口。

这样,如果有人在您编写了反向方法之后编写了一个新的,更好的NodeList实现,并且您不必为{{1}的每个新实现调整代码,那么您的代码仍然有效。 }。

答案 3 :(得分:6)

参数需要一个对象,该类实现一个接口(参数)。

Java代码:

void reverse(NodeList node) {
    // your code
}

等于:

reverse(x) {
    if(x == null || x instanceof NodeList) {
         // your code
    }else throw new RuntimeException("Some sort of error.");
}

请注意;在此处阅读有关接口的更多信息:http://java.sun.com/docs/books/tutorial/java/IandI/interfaceAsType.html

答案 4 :(得分:2)

在学习lambda的时候也有同样的困惑。 这段视频没有解释这个概念,但它是一个明确的方式,让您了解它如何在将界面作为参数传递方面发挥作用。

https://www.youtube.com/watch?v=mk3erzL70yM

答案 5 :(得分:1)

使用接口IMHO的主要好处是能够轻松测试。假设您有一个名为PatientManager的接口。

您可以为可想象的事情编写特定的单元测试,例如“CachingPatientManager”或“LDAPPatientManager”,用例可能是无数的。

好处是因为接口编程变得高度可重用和可测试。

答案 6 :(得分:1)

您无法创建接口的实例(/对象)。 是的,您可以将Interface作为参数传递给函数。但问题似乎不完整。界面不是由任何类实现的。缺了点什么。如果您尝试运行此命令,编译器将不会显示任何错误。

但是,在reverse()方法中,您需要创建一个实现NodeList接口的类实例。我希望这是有道理的。

答案 7 :(得分:1)

这是一种可能的实施方式:

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());
        }
}

节目输出:

Before reversal
1->2->3->null

After reversal
3->2->1->null

我很想知道这个问题是否可以通过使用匿名类来解决。有什么想法吗?