1

有人可以在下面的示例中解释为什么接口方法在类构造函数中作为参数传递时可以直接调用吗?我尝试在 Java 语言规范中搜索规则但找不到。

public interface Interface {
    public void foo();
}

public class Main {
    public Main() {}
    public Main(Interface obj) {obj.foo();}
    public static int test() {return 123;}
}
4

4 回答 4

3

只是一种多态行为,Java 期望实现该接口的方法。这意味着,任何实现该方法的类都是一个Interface,因此您可以对该方法有许多不同的实现。比方说:

public class ImplementedInterface implements Interface
{
    public void foo()
    {
        System.out.println("Hey!, i'm implemented!!");
    }
}

所以当你打电话时:

Interface aux = new ImplementedInterface();
Main m = new Main(aux);

文字“嘿!,我被执行了!!” 将被打印。

于 2013-07-05T02:05:42.877 回答
1

您可以从引用中调用foo方法,Interface因为它只能包含实现的类的对象Interface,因此它将为foo方法提供主体。

现在由于后期绑定,Java 将在需要时使用对象类的代码。

于 2013-07-05T02:07:38.637 回答
1

我认为你很困惑,你认为它是接口类型它是一个接口

public Main(Interface obj) {
  obj.foo();
}

obj 是来自Interface.

您可能希望看到一些采用这种方法的常见设计模式,例如Strategy Pattern

例如 :

public interface Searcher {
  void search(String text, List<String> words);
}

public class BinarySearcher implements Searcher{
   @Override
   public void search(String text , List<String> words){
      //code here
   }

}

public class LinearSearcher implements Searcher{
     @Override 
     public void search(String text ,List<String> words ){
           // code here
     }
}

public class WordContext {

private Searcher searcher;
private List<String> words;

public void makeSearch(String text){
    searcher.search(); // you only know at runtime what subtype will be searcher
}

// here you inject by contract
public void setSearcher(Searcher searcher){
  this.searcher= searcher;
}

// here you inject by contract
public void setWords(List<String> words){
   this.words = words;
}

}

这是您通过抽象合同而不是具体实现来指导的主要优势。在这个例子中,您可以更改注入它的搜索器,可以是线性搜索器或二进制搜索器,这就是多态魔法!

于 2013-07-05T02:10:53.043 回答
0

这就是Programming to an interface, not an implementation发挥作用的地方。您的方法期望实现的类的对象interface

我会用一个例子来解释它。

让我们说我有 LinkedList<String> ll = new LinkedList<String>();

我有 ArrayList<String> al = new ArrayList<String>();

现在我有一个方法 -

public void deleteFirst(List aList) {
  System.out.println(aList.remove(0));
 }

现在您可以将ll和传递al给该deleteFirst方法。这意味着您的方法被传递了一个实现interface.

在示例中ArrayListLinkedList两者都实现了List接口,因此可以传递给方法。最终,您的方法得到的是实现List接口的类的对象。

于 2013-07-05T02:06:00.987 回答