Java基礎學習:6.接口實例化?不,其實是一種簡寫方式

點擊跳轉到原文
今天在看的代碼的時候,發現居然有個“實例化接口”的代碼,驚了,代碼如下:

public class testCollections {
    public static void main(String[] args) {
        ArrayList<Integer> list1 = new ArrayList<>();
        list1.add(2);
        list1.add(6);
        list1.add(3);
        list1.add(5);
        list1.add(1);
        //Collections.sort(list1);
        Collections.sort(list1,new Comparator<Integer>() {
            @Override
            public int compare(Integer o1, Integer o2) {
                return o1-o2;
            }
        });
        System.out.println(list1);
    }
}

但是我們明明一直了解的是接口和抽象類是不能new的,怎麼這裏就可以了,上網百度了了好久,關於這個問題解釋的,真的好少,最終找到一篇文章解釋:其實並沒有真正地實例化,new了一個實現接口的匿名內部類,然後new得到匿名內部類的對象再向上轉型爲它實現的接口(原始類型)
原文如下(其實我還是有點沒看懂,後面再找大神問下吧,暫時先記着)

先給大家看一個常用的代碼:

tv1.setOnClickListener(new OnClickListener() {

        @Override
        public void onClick(View v) {
            // TODO Auto-generated method stub
            
        }
    });

注意到OnClickListener,Ctrl +左鍵進入源碼看到,
public interface OnClickListener {
/**
* Called when a view has been clicked.
*
* @param v The view that was clicked.
*/
void onClick(View v);
}

我們在學習Java基礎的時候知道,接口是不可以實例化的,那爲什麼上面OnClickListener可以new,這不得不讓我們問一下,到底接口能不能實例化。答案是:NO!
解釋一下,這是匿名內部類的寫法。new OnClickListener(){}其實並沒有真正地實例化,new了一個實現接口的匿名內部類,然後new得到匿名內部類的對象再向上轉型爲它實現的接口(原始類型)。這樣解釋可能還不夠,再讓大家看一段代碼:

class MyListener implements OnClickListener {
@Override
public void onClick(View v) {
}
}

tv1.setOnClickListener(new MyListener());

這樣寫大家就不會有任何的疑惑了,因爲不再看到接口被實例化了錯覺。我們看到只是一種省略的寫法,它實例化了一個匿名內部類,而這個類實現了一個接口。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章