Java 匿名对象与匿名内部类的使用

 更新时间:2024年01月31日 15:25:09   作者:雨翼轻尘  
很多小伙伴对匿名对象和匿名内部类的写法有点陌生,本文主要介绍了Java 匿名对象与匿名内部类的使用,具有一定的参考价值,感兴趣的可以了解一下

很多小伙伴对匿名对象和匿名内部类的写法有点陌生,这里专门写一篇来帮助大家认识一下他们的写法。

一、匿名对象

比如现在有一个Student类,里面啥也没有写:

/**
 * ClassName: Student
 * Package: PACKAGE_NAME
 * Description:
 *
 * @Author 雨翼轻尘
 * @Create 2024/1/31 0031 11:39
 */
public class Student {

}

然后还有一个测试类Test

/**
 * ClassName: Test
 * Package: PACKAGE_NAME
 * Description:
 *
 * @Author 雨翼轻尘
 * @Create 2024/1/31 0031 11:39
 */
public class Test {
    public static void main(String[] args) {
        //类->对象  格式:类名Student 对象名stu = new 类名Student();
        Student stu=new Student();
    }
}

类->对象

格式:类名Student 对象名stu = new 类名Student();

如下:

public class Test {
    public static void main(String[] args) {
        //类->对象  格式:类名Student 对象名stu = new 类名Student();
        Student stu=new Student();
    }
}

现在打印出来就是地址值

image.png

如果这样,也是地址值

image.png

new一次,就会创建一个对象,相当于在堆中开辟了一块空间,所以地址值都不一样,如下:

public class Test {
    public static void main(String[] args) {
        //类->对象  格式:类名Student 对象名stu = new 类名Student();
        Student stu=new Student();
        System.out.println(stu);    //test.Student@4eec7777
        System.out.println(new Student());  //test.Student@3b07d329
        System.out.println(new Student());  //test.Student@41629346
    }
}

上面的stu是有名字的对象,而现在的new Student()没有对象名,叫做匿名对象

有了new关键字,就表示在堆里面创建了一个新的空间。

现在在Student类里面加上属性,比如:

public class Student {
    String name;    //姓名
}

正常情况下,name可以赋值:

public class Test {
    public static void main(String[] args) {
        //类->对象  格式:类名Student 对象名stu = new 类名Student();
        Student stu=new Student();
        System.out.println(stu);    //test.Student@4eec7777
        stu.name="张三";
        System.out.println(stu.name);   //张三

    }
}

打印出来就是“张三”:

image.png

🎲那么new Student()可以给name赋值吗?

是可以的。

它是一个匿名对象,虽然没有名字,但是它可以给属性赋值的。如下:

public class Test {
    public static void main(String[] args) {
        System.out.println(new Student().name="李四");  //test.Student@3b07d329
        System.out.println(new Student());  //test.Student@41629346
    }
}

输出:

image.png

匿名对象”只不过是一个没有名字的对象而已,依然是一个对象。

若是方法依然可以调用的,比如现在写一个方法eat,如下:

public class Student {
    String name;    //姓名

    public void eat(){
        System.out.println("使劲吃...");
    }
}

测试类里面:

public class Test {
    public static void main(String[] args) {
        //类->对象  格式:类名Student 对象名stu = new 类名Student();
        Student stu=new Student();
        System.out.println(stu);    //test.Student@4eec7777
        stu.name="张三";
        System.out.println(stu.name);   //张三
        stu.eat();

        System.out.println(new Student().name="李四");  //test.Student@3b07d329
        System.out.println(new Student());  //test.Student@41629346
        new Student().eat();
    }
}

输出结果:

image.png

像这样直接new了一个类名,但是没有给对象名的,叫做“匿名对象”。

区别就是,有名的对象它可以多次使用,而匿名对象却只能使用一次。

二、匿名内部类

提供一个接口IA,里面写一个抽象方法play,如下:

package test;

/**
 * ClassName: IA
 * Package: test
 * Description:
 *
 * @Author 雨翼轻尘
 * @Create 2024/1/31 0031 12:08
 */
public interface IA {
    //抽象方法
    void play();
}

抽象方法省略了public abstract

抽象方法要想重写,需要有子类去实现这个接口

接下来写一个实现类IAImpl,将接口里面的抽象方法重写一下,如下:

package test;

/**
 * ClassName: IAImpl
 * Package: test
 * Description:
 *
 * @Author 雨翼轻尘
 * @Create 2024/1/31 0031 12:12
 */
public class IAImpl implements IA{
    @Override
    public void play() {
        System.out.println("打游戏...");
    }
}

然后再来一个测试类IATest,以多态的方式创建接口:

package test;

/**
 * ClassName: IATest
 * Package: test
 * Description:
 *
 * @Author 雨翼轻尘
 * @Create 2024/1/31 0031 12:14
 */
public class IATest {
    public static void main(String[] args) {
        IA ia=new IAImpl(); //多态
    }
}

IA ia=new IAImpl(); ,接口不能传对象,口诀:多态–“父父new子”。

实现类可以看成继承关系。

现在来使用ia调用play方法:

public class IATest {
    public static void main(String[] args) {
        IA ia=new IAImpl(); //多态
        ia.play();	//编译看左,运行看右
    }
}

输出:

image.png

ia.play(); “编译看左,运行看右”,接口IA里面有play方法,它被实现类IAImpl重写了,所以执行的时候是看实现类里面的。

现在我们来看一下这个蓝色部分,这个括号里面只有一个方法的重写:

image.png

之前说接口不能new,我们来看一下这样:

image.png

🎲看一下刚才的两个蓝色部分,有什么区别?

image.png

没有区别!只不过右边多了一个最后的分号。

既然花括号里面的内容和实现类的一模一样,那我们可以使用i调用里面的方法play,如下:

public class IATest {
    public static void main(String[] args) {
        IA ia=new IAImpl(); //多态
        ia.play();  //编译看左,运行看右

        System.out.println("------------------");

        IA i=new IA() {
            @Override
            public void play() {
                System.out.println("打游戏哈哈哈...");
            }
        };

        i.play();
    }
}

打印输出:

image.png

可以看到,调用的是花括号里面重写IA接口的方法。

我们new了一个接口之后,后面的大括号里面可以看作一个类的结构。如下:

image.png

在花括号里面是对方法的重写,重写的是IA接口的抽象方法

现在写一个IB接口

public interface IB {
    //抽象方法
    void sleep();
}

再写一个测试类IBTest

public class IBTest {
    public static void main(String[] args) {

    }
}

目前IB接口没有实现类,还可以创建对象吗?

可以的,如下:

public class IBTest {
    public static void main(String[] args) {
        IB ib=new IB() {
            @Override
            public void sleep() {

            }
        };
    }
}

这个结构和它的实现类结构是一样的(蓝色部分):

image.png

现在就不需要接口的实现类了,上面蓝色部分就是它的匿名实现类

通过ib.sleep()来调用重写的抽象方法:

public class IBTest {
    public static void main(String[] args) {
        IB ib=new IB() {
            @Override
            public void sleep() {
                System.out.println("睡觉...");
            }
        };

        ib.sleep();
    }
}

输出:

image.png

这就是匿名内部类,new的接口,相当于是把实现类的结构拿了过来,重写了一下。

🍰还有一种写法。

刚才说了匿名对象,可以直接拿匿名对象去调用方法。

同样,我们还可以使用匿名内部类直接调用方法

这个叫做创建“匿名实现类的有名对象”,如下结构:

IB ib = new IB(){
    //sleep()方法的重写
};
ib.sleep();	//用ib调用方法sleep()

现在我们直接new一个接口IB

new IB(){
    //sleep()方法的重写
}

然后直接用它调用sleep()方法,如下:

new IB(){
    //sleep()方法的重写
}.sleep();

🌱代码

public class IBTest {
    public static void main(String[] args) {
        IB ib=new IB() {
            @Override
            public void sleep() {
                System.out.println("睡觉...");
            }
        };

        ib.sleep();

        System.out.println("-------");

        new IB(){
            @Override
            public void sleep() {
                System.out.println("晚安喽");
            }
        }.sleep();
    }
}

🍺输出

image.png

这里的ib就表示:

image.png

那就可以直接拿它调用sleep()方法:

image.png

🚗看一下正常的一般写法:

image.png

再看一下这两种方式:

image.png

到此这篇关于Java 匿名对象与匿名内部类的使用的文章就介绍到这了,更多相关Java 匿名对象与匿名内部类内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家! 

您可能感兴趣的文章:

相关文章

  • springboot实现浏览器截屏并添加文字

    springboot实现浏览器截屏并添加文字

    大家好,本篇文章主要讲的是springboot实现浏览器截屏并添加文字,感兴趣的同学赶快来看一看吧,对你有帮助的话记得收藏一下
    2022-02-02
  • 详解Java如何优雅的使用策略模式

    详解Java如何优雅的使用策略模式

    设计模式是软件设计中常见问题的典型解决方案。 它们就像能根据需求进行调整的预制蓝图, 可用于解决代码中反复出现的设计问题。今天就拿其中一个问题来分析如何优雅的使用策略模式吧
    2023-02-02
  • Java 事务详解及简单应用实例

    Java 事务详解及简单应用实例

    这篇文章主要介绍了Java 事务详解及简单应用实例的相关资料,java事务能够保证数据的完整性和一致性,当然这是书本上的知识,具体如何应用这里举例说明,需要的朋友可以参考下
    2016-12-12
  • mybatis框架order by作为参数传入时失效的解决

    mybatis框架order by作为参数传入时失效的解决

    这篇文章主要介绍了mybatis框架order by作为参数传入时失效的解决方案,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2021-06-06
  • JFINAL+Ajax传参 array 数组方法 获取request中数组操作

    JFINAL+Ajax传参 array 数组方法 获取request中数组操作

    这篇文章主要介绍了JFINAL+Ajax传参 array 数组方法 获取request中数组操作,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2020-08-08
  • SpringAOP 如何通过JoinPoint获取参数名和值

    SpringAOP 如何通过JoinPoint获取参数名和值

    这篇文章主要介绍了SpringAOP 通过JoinPoint获取参数名和值的操作,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2021-06-06
  • Java使用字节流实现图片音频的复制

    Java使用字节流实现图片音频的复制

    今天带大家学习Java的相关知识,文章围绕着Java如何使用字节流实现图片音频的复制展开,文中有非常详细的介绍,需要的朋友可以参考下
    2021-06-06
  • 使用maven如何将项目中的test代码打包进jar中

    使用maven如何将项目中的test代码打包进jar中

    这篇文章主要介绍了使用maven如何将项目中的test代码打包进jar中,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2022-03-03
  • Spring Boot+Drools规则引擎整合详解

    Spring Boot+Drools规则引擎整合详解

    本篇文章主要介绍了Spring Boot+Drools规则引擎整合,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2017-09-09
  • Java反射机制深入理解

    Java反射机制深入理解

    这篇文章主要介绍了Java反射机制深入理解的相关资料,希望通过本文大家能理解这部分内容,需要的朋友可以参考下
    2017-09-09

最新评论