一篇文章带你学会匿名内部类,由浅入深,一定手把手教会你

一篇文章带你学会匿名内部类,由浅入深,一定手把手教会你听名字就能看得出来 内部类 就是定义类中的一个类

目录

1. 匿名内部类的语法格式

2. 常规类举例

3. 匿名内部类的推演过程

4. 匿名内部深层分析

5. 匿名内部类有什么用?

5.1 问题引入

5.2 解决思路

5.3 巧用匿名内部类解决代码冗余

5.4 牢记匿名内部类创建的也是一个对象哦!


1. 匿名内部类的语法格式

匿名内部类的定义:匿名内部类我们从字面上的意思理解就可以了, "匿名" 就是没有名字,"内部类" 就是在其它类内部的一个类,合在一起的意思就是 "在其它类中没有名字的内部类"。

匿名内部类的语法格式也比较简单,如下图所示;

对于匿名内部类而言,它里面整体包含了三个部分,继承/实现,方法重写,创建对象。各位童鞋先把匿名内部类的格式混个眼熟,下面我们一点一点来推演匿名内部类为什么是这样的格式

2. 常规类举例

因为直接讲解可能会有很多同学懵,不知道所以然,所以我们先从 Java 中最为常规的类举例说起,一点点带你解析匿名内部类的由来。

如下所示,我先创建一个 Swim 游泳接口

// 创建一个 Swim 游泳接口 public interface Swim { // 定义一个抽象方法,用于让子类重写实现具体行为 public abstract void swim(); }

现在我来提问,如果我现在要调用 swim 方法,该怎么做?

答案也呼之欲出了吧!使用我们最为常规的方法,可以定义一个类然后实现 Swim 游泳接口,然后重写接口中的方法,再然后创建定义出来的那个类对象,利用类对象调用重写的 swim 游泳方法就可以了。

好的,既然这么说了,下面我们就来试着做一下,代码已经写好了如下所示

// 定义一个学生类实现 Swim 游泳接口 public class Student implements Swim{ // 重写 Swim 接口中的游泳方法 @Override public void swim() { // 为了演示简单打印一句话,不做逻辑复杂的语句 System.out.println("重写的游泳方法"); } // 定义 main 方法 public static void main(String[] args) { // 创建 Student 类的对象 s1 Student s1 = new Student(); // 让对象 s1 调用实现的方法 s1.swim(); } }

经过上面的代码书写,我们已经完成了所有的步骤,现在来运行上述方法,我们就可以达到我们想要的结果了,运行结果如下图所示

3. 匿名内部类的推演过程

上面的常规类代码相比对于各位同学来说应该是小意思,那么现在我们来对上面的代码做一个分析。

Student 就是类的名字,实现了 Swim 接口,大括号体内部的所有东西就是当前类的所有内容。

(1)推理第一步:现在我这样做,我把大括号前面的内容全部删掉,只留大括号内部的内容,如下所示,仔细分析可以看出,此时这个类是一个没有名字的类,而且重写了 swim 方法,内部类三要素之一的方法重写已经出现了。

(2)推理第二步:这个没有名字的类重写的方法正是 Swim 接口中的方法,所以说这个没有名字的类实现了 Swim 接口,匿名内部类三要素之一的继承/实现也出现了。

既然这个没有名字的类实现了 Swim 接口,我们姑且把 Swim 接口放在这个没有名字的类的前面,如下图所示

 (3)推理第三步:创建对象,我们先来回顾普通创建对象时的创建方法,基本都是使用 new Object() 的方式,而匿名内部类也是一样的道理,既然我们要创建对象,当然也是采用 new ... 的方式,接着刚才第二部的推理,我们将 new 关键字放在 Swim 的前面,将 "()" 放在 Swim 的后面,就得到了如下的样子,匿名内部类三要素之一的创建对象也完成了

此时我们来对比刚才匿名内部类的语法格式,可以发现已经完全你全匹配上了,我们也可以简单的这样理解匿名的推演过程

4. 匿名内部深层分析

经过了上面的推演过程,想必各位同学对于匿名内部类的格式已经有了更好的理解。

精炼成一句话来说就是,"匿名内部类是指大括号内部的那部分代码才是真正的没有名字的类,这个没有名字的类继承或者实现了方法体之前的那个类或接口,最前面的 new 关键字是创建对象用的,new 出来的对象其实就是后面大括号内部没有名字的那个类的对象"。

5. 匿名内部类有什么用?

5.1 问题引入

OK,上面我们大篇幅地讲解了匿名内部类的推演和底层逻辑,估计现在很多同学都会很疑惑,这玩意有啥用啊,我看不出来它有什么好处和优点?

我给大家就一个场景提问一个问题,你就知道它有什么用了。

如下代码,我定义了一个 Animal 接口,

public interface Animal { void eat(); }

在另一个类中,我定义了一个静态方法,并且方法的参数需要传递一个 Animal 类型的对象,

public class Test6 { public static void method(Animal a){ a.eat(); } }

现在,我要在测试类中调用 method 方法,该怎么办?

5.2 解决思路

各位同学要知道,现在 Animal 是个接口,我们不能通过接口去创建对象,所以按照正常的逻辑来说,我们必须创建一个类去实现 Animal 接口,并重写 Animal 接口中的方法,然后再创建 Animal 接口的实现类对象,将对象传递给 method 方法,然后才能调用 Animal 接口中的方法。

如下代码展示

// 创建 Dog 类 实现 Animal 接口 public class Dog implements Animal{ // 重写Animal 中的方法 @Override public void eat() { System.out.println("狗吃东西"); } }
public class Test6 { public static void method(Animal a){ a.eat(); } public static void main(String[] args) { // 创建一个狗对象 Dog dog = new Dog(); // 将 dog 对象作为参数传递给 method method(dog); } }

此时运行 main 方法,就可以得到我们的结果,在控制台得到 "狗吃东西" 的运行结果

5.3 巧用匿名内部类解决代码冗余

通过刚才举的例子和我们的代码解决方案,不难看出,传统的解决思路虽然可以达到目的,却是极为麻烦,带来了大量的代码冗余。如果这个实现类我只使用一次,会不会很浪费。而且这才只是一个接口,如果还有别的静态方法和这个一样,其实会对开发造成一定的影响。

但如果现在我们使用匿名内部类的话,就可以极大地简化开发,提高效率。

代码如下所示,我们完全不需要创建一个类去实现 Animal 接口,直接使用匿名内部类的方式创建 Animal 接口的方法,并在匿名内部类方法内部直接重写 Animal 接口的 eat 方法。这样非常非常简化将代码,极大的提高了开发效率,也避免了代码的冗余

public class Test6 { public static void method(Animal a){ a.eat(); } public static void main(String[] args) { method(new Animal() { @Override public void eat() { System.out.println("狗吃东西"); } }); } }

运行结果如下所示,同样可以达到相同的效果

5.4 牢记匿名内部类创建的也是一个对象哦!

各位同学不要忘记了,匿名内部类语法本身创建出来的就是一个对象,既然是一个对象,那么对象 Object 类中的方法它都有,它也可以作为对象调用它自己的方法,下面我就来给同学们展示一些匿名内部类花里胡哨的玩法。

如下代码,我们都知道接口不能创建对象,但现在我利用匿名内部类的方式就能创建 Animal 接口的对象,还能重写 eat 方法,

public class Test6 { public static void main(String[] args) { // 采用多态+匿名内部类的方式创建 Animal 接口的对象 Animal animal = new Animal() { @Override public void eat() { System.out.println("猫吃小鱼"); } }; // 调用 animal 对象中的方法 animal.eat(); } }

不仅如此,创建出来的 animal 对象还可以调用它自己重写的 eat 方法,是不是很巧妙呀!

运行如下,完全没有问题

今天的文章 一篇文章带你学会匿名内部类,由浅入深,一定手把手教会你分享到此就结束了,感谢您的阅读。
编程小号
上一篇 2024-10-20 23:17
下一篇 2024-10-20 23:11

相关推荐

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
如需转载请保留出处:https://bianchenghao.cn/bian-cheng-ji-chu/3911.html