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

这样写大家就不会有任何的疑惑了,因为不再看到接口被实例化了错觉。我们看到只是一种省略的写法,它实例化了一个匿名内部类,而这个类实现了一个接口。

发布了33 篇原创文章 · 获赞 5 · 访问量 2万+

猜你喜欢

转载自blog.csdn.net/qq_41623154/article/details/105124736