前言

首先声明,用接口或者抽象类实例化一个对象是不可能的,错误的。


接口、抽象类实现注意点

  1. Interface
  • 属性默认都是 public static final
  • 方法默认都是 public abstract
  • 都不用显示声明
  1. 抽象类
  1. 至少含有一个方法是abstract修饰的

Get right to the point

现在,我们动手解释下为什么用接口或者抽象类实例化对象是错误的,以及该如何重新理解这句话。

首先,我们声明一个接口:

通过接口创建对象java 接口能够创建对象_开发工具


再声明一个抽象类:

通过接口创建对象java 接口能够创建对象_实例化_02

在eclipse中当我们为抽象类或者接口实例化对象时,显然它会报错:

通过接口创建对象java 接口能够创建对象_开发工具_03


报错显示,这两个是抽象的,是不能实例化的。

如此,从直观角度来看实例化接口和抽象类是肯定不对的。

但是我相信很多朋友是因为看到了如下这种情况才会有疑惑的:

通过接口创建对象java 接口能够创建对象_java_04


很多朋友会说,是啊,你看它这不是创建了一个接口的对象么?

问题便出在了这里,先暂且不急,我们再尝试在IDEA中“创建”对象:

通过接口创建对象java 接口能够创建对象_java_05

通过接口创建对象java 接口能够创建对象_开发工具_06

我们会发现IDEA自动为我们补全了创建匿名内部类的代码,并且要求我们实现抽象方法,同时声明一个引用来指向这个匿名内部类生成对象。

所以现在想想,平常我们经常听到人问interface能创建一个对象,从经历来看,主要存在两方面的误解:

  1. 错把引用当做对象
  2. 通过接口创建对象java 接口能够创建对象_实例化_07

  3. 新人错误的认为这就是创建了一个接口的对象,殊不知,这只是声明了一个引用。
    我们来正确理解下平常的对象的声明语句:
  4. 通过接口创建对象java 接口能够创建对象_通过接口创建对象java_08

  5. 我们知道”=”号右边先执行,即 new 了一个Myclass对象,这时我们无法对这个对象操作,所以又声明了一个名为 myclass 的引用指向这个对象,这样我们就可以通过操作 myclass 来操作对象。在这里,对象和对“对象”的引用大家要分清,这是两个概念。
  6. 从来不能创建一个接口的对象,创建接口对象本身就是一个错误的说法。
  7. 通过接口创建对象java 接口能够创建对象_java_09

  8. 对于这段代码,我们正确的解读是:
    我们通过一个内部类实现了接口里的抽象方法并且返回一个内部类对象,之后我们通过接口的引用捕获这个对象。

Extension Problems:
但是,根据上面的解释,又会有新的问题出现:

  1. 怎么才算是创建(实例化)对象?
    答:所谓实例化一个对象,在java中从本质上来讲是从堆里申请到内存分配给这个对象,一个对象应该是一个存在内存中的实体,里面存储着属性和方法等。
  2. 为什么会用一个接口的引用去捕获这个对象?为什么不用类的引用去捕获?
    答:这个涉及到转型的知识点,这样做的作用请参考我另一篇博客。