顾名思义 匿名 就是没有名字,一个没有名字的内部类,称为匿名内部类。
下面先看一个例子,比如说你想和你的女朋友去看春节档的《唐人街探案三》
这个时候我们要先定义一个接口,去看唐探3的接口
public interface MyInterface {
// 看电影的抽象方法
void watchFilm();
}
OK!现在我们有了一个接口,接口里面有一个看电影的抽象方法。而现在你要去看电影了,你要实现接口里面的方法,但是接口不能直接 new 出来,所以你就要先定义一个实现类去实现这个接口,代码如下:
public class MyInterfaceImpl implements MyInterface{
public void watchFilm() {
System.out.println("实现方法里带着女朋友去看电影!");
}
}
现在我们实现了这个接口,也可以去看电影了,我们现在要写一个主方法;
public class GoWatchFilm {
public static void main(String[] args) {
MyInterfaceImpl myInterface = new MyInterfaceImpl();
myInterface.watchFilm();
}
}
而这个时候,我们要先 new 一个看电影的实现类,然后调用里面看电影的方法,如图:
现在你和你心爱的女朋友成功的看到了电影…
因为我们已经知道多态,我们还可以使用多态的方式," = " 的左边时接口,右边是实现类也是没毛病的,
到这里!那么问题来了,这个电影你就看了一次,只有在 new 的时候才看了一次,没有再看第二次。所以这个时候我们就可以使用 匿名内部类 了。
如果接口的实现类(或者父类的子类)只需要使用唯一一次,那么这种情况下我们就可以省略掉对该类的定义,而改为使用匿名内部类。
匿名内部类的定义格式:
上面我们有说到接口不能直接 new ,如果直接new就会报错,而这次,我们就直接new接口,但是这里的new和new对象又有一点小差别,格式如下:
接口名称 对象名 = new 接口名称(){
// 覆盖重写所有抽象方法
}
那我们就代码实现一下:
如上图,我们new了一个接口,而接口下面的 { } 里面就是一个匿名内部类,所以现在我们使用匿名内部类就可以带着女朋友把电影看玩了,而之前我们定义的一个实现类就可以不用了,虽然说这样写法有点怪异,但是我们是想带着女朋友看电影,并且这个电影只需要看一次就行了,往后就不看了,却还要写一个实现类去实现它,使用匿名内部类就可以省掉一个类的单独定义,看到这想必小伙伴已经对匿名内部类了解的差不多了,不过匿名内部类也有一些注意事项,我们接着往下看。
首先对格式 “new 接口名称 () {…}” 进行解析:
1.new 代表创建对象的动作;
2.接口名称就是匿名内部类需要实现哪个接口;
3. {…} 这才是匿名内部类的内容; PS:没有class,没有名称
另外还要注意以下几点问题:
如果现在你的女朋友还想要看完电影去吃个海底捞,那么我们现在在接口里再写一个方法。并且第二天的时候你美丽的女朋友还要重复昨天做的事情,看电影,吃火锅,开始撸代码:
public interface MyInterface {
// 看电影的抽象方法
void watchFilm();
// 吃海底捞的抽象方法
void eatHotPot();
}
public class GoWatchFilm {
public static void main(String[] args) {
/* MyInterface myInterface = new MyInterfaceImpl();
myInterface.watchFilm();*/
MyInterface day01 = new MyInterface() {
@Override
public void watchFilm() {
System.out.println("第一天在匿名内部类里面实现了带女朋友看电影了!!!!!!");
}
@Override
public void eatHotPot() {
System.out.println("第一天看完电影我们去吃一个火锅吧!!!!");
}
};
day01.watchFilm();
day01.eatHotPot();
// 来一条分割线
System.out.println("-------------------------------------------------------------------------------------------");
new MyInterface() {
@Override
public void watchFilm() {
System.out.println("第二天在匿名内部类里面实现了带女朋友看电影了!!!!!!");
}
@Override
public void eatHotPot() {
System.out.println("第二天看完电影我们去吃一个火锅吧!!!!");
}
}.watchFilm();
new MyInterface() {
@Override
public void watchFilm() {
System.out.println("第二天在匿名内部类里面实现了带女朋友看电影了!!!!!!");
}
@Override
public void eatHotPot() {
System.out.println("第二天看完电影我们去吃一个火锅吧!!!!");
}
}.eatHotPot();
}
}
输出内容:
第一天在匿名内部类里面实现了带女朋友看电影了!!!!!!
第一天看完电影我们去吃一个火锅吧!!!!
-------------------------------------------------------------------------------------------
第二天在匿名内部类里面实现了带女朋友看电影了!!!!!!
第二天看完电影我们去吃一个火锅吧!!!!
可以看到,当我们第一天的时候,看完电影再吃火锅时是用的匿名内部类,是有对象名称的,可以直接用对象名称调用吃火锅和看电影的方法,而当第二天想再次调用的时候如果我们是用到了匿名对象,是直接new接口没有对象名称就要new两次,然后分别调用看电影和吃火锅,并且每次都要重写接口里的所有方法。
1、匿名内部类,在创建对象的时候只能使用一次,如果希望多次创建对象,而且内容一样的话,那么此时我们就要使用单独定义的实现类了。
2、匿名对象,在调用方法的时候,只能调用唯一一次,如果希望同一个对象调用多次方法,就必须给对象起一个名字。
3、匿名内部类是省略了“实现类/子类名称”,但是匿名对象是省略了“对象名称”
到这里小伙伴们差不多已经知道匿名内部类的含义了吧,并且我们什么时候能用到匿名内部类,什么时候要定义一个实现类去实现接口里的方法了吧!!!!