• Java 内部类 匿名类 匿名内部类


    以下均来源于网络整理

    一、内部类

    https://www.cnblogs.com/wfq9330/p/8760031.html 

    定义:根据创建位置的不同,分为成员的、方法的、匿名的。接口中的内部类叫做接口内部类。 
    理解:在类的内部创建,那就是类的一部分,跟属性、方法同级。这也就解释了为何能访问外部私有成员,我是你的一部分,我当然可以访问了

    1、成员内部类

    class Outer {
        private int i = 1; 
    
        class Inner { 
            public void fun() {System.out.println("Outer I=" + i)} 
        } 
    } 

    2、方法内部类

    class Outer{
    
        private String test;
    
        public void fun() {
            final int i = 1; // 被方法内部类访问的局部变量必须被final修饰
    
            class Inner { // 方法内部类 不能有访问修饰符,比如public
                public void print() {
                    System.out.println("Method I=" + i + test);
                }
            }
        }
    }

    3、匿名内部类

    interface USB {
        public abstract void start()
    }
    
    class Outer{
    
        public void fun() {
            final int i = 1; // 被匿名内部类访问的局部变量必须被final修饰
            new USB(){
                @Override
                public void start(){
                        System.out.println("local_var_i=" + i);
                }
            }.start();
        }
    }        

    4、静态内部类

    class Outer{ 
        private int i = 1; 
    
        static class Inner{ // 不能访问外部类的非静态成员
            public void fun() {
    
             } 
        } 
    }        

    5、接口内部类

    interface USB { 
        class Inner { // 默认是public static,即可以直接new USB.Inner();
        } 
    } 

    二、匿名内部类

    https://www.cnblogs.com/nerxious/archive/2013/01/25/2876489.html

    匿名内部类也就是没有名字的内部类

    正因为没有名字,所以匿名内部类只能使用一次,当然也就不能有构造器

    但使用匿名内部类:必须继承一个父类或实现一个接口

    使用匿名内部类课使代码更加简洁、紧凑,模块化程度更高。

    内部类能够访问外部内的一切成员变量和方法,包括私有的,而实现接口或继承类做不到,所以匿名内部类作用大

    1、匿名内部类的基本实现

    abstract class Person {
        public abstract void eat();
    }
     
    public class Demo {
        public static void main(String[] args) {
            Person p = new Person() {
                public void eat() {
                    System.out.println("eat something");
                }
            };
            p.eat();
        }
    }

    运行结果:eat something

    红色加粗的代码,就是匿名内部类,继承了 Person 类,却没有给出这个类的名字,直接实例化它并赋值给 p

    如果不用匿名内部类,我们会这样写

    abstract class Person {
        public abstract void eat();
    }
     
    class Child extends Person {
        public void eat() {
            System.out.println("eat something");
        }
    }
     
    public class Demo {
        public static void main(String[] args) {
            Person p = new Child();
            p.eat();
        }
    }
    运行结果:eat something

    先定义一个类,名字叫Child,用到的时候,Person p = new Child(); 用它的名字实例化它,然后赋值给 p,对比发现,定义匿名内部类,后面有大括号接类的方法,普通的实例化,没有大括号的内容

    2、在接口上使用匿名内部类

    interface Person {
        public void eat();
    }
     
    public class Demo {
        public static void main(String[] args) {
            Person p = new Person() {
                public void eat() {
                    System.out.println("eat something");
                }
            };
            p.eat();
        }
    }

    运行结果:eat something

    3、Thread类的匿名内部类实现

    public class Demo {
        public static void main(String[] args) {
            Thread t = new Thread() {
                public void run() {
                    for (int i = 1; i <= 5; i++) {
                        System.out.print(i + " ");
                    }
                }
            };
            t.start();
        }
    }
    运行结果:1 2 3 4 5

    4、Runnable接口的匿名内部类实现

    public class Demo {
        public static void main(String[] args) {
            Runnable r = new Runnable() {
                public void run() {
                    for (int i = 1; i <= 5; i++) {
                        System.out.print(i + " ");
                    }
                }
            };
            Thread t = new Thread(r);
            t.start();
        }
    }
    运行结果:1 2 3 4 5

    三、匿名类

      我个人理解,一个没有名字的类--匿名类,必须依赖于一个现有的类中,才能存在,你在类外部定义一个匿名类,语法是通不过的,所以匿名类就是匿名内部类

    四、特殊点

    链接:https://www.zhihu.com/question/49330534/answer/115478102
    除了只能使用一次,其实还有其他用处(在看spring-boot源码时发现的)
    当你想使用一个类的protected 方法时,但是又不和这个类在同一个包下,你是没办法调用的。
    这时候匿名类就派上用场了,你可以声明一个匿名类继承该类,并定义一个方法,在这个方法内使用super调用你想调用的那个方法(其实你也可以写个类继承这个类,就能调用父类的protected方法了,但是匿名类更简洁,因为你只想调用这个方法而已)

    五、匿名对象与匿名内部类

    匿名对象:没有名字的对象。

    非匿名对象:

    ClassName c=new ClassName();

    c.run();

    匿名对象:

    new ClassName().run();

    注意事项:

    1、当对象对方法仅进行一次调用的时候,就可以简化成匿名对象。

    2、两个匿名对象不可能是同一个对象。

    3、一般不给匿名对象赋予属性值,因为永远无法获取到。

    4、运行一次,直接就被回收掉了,节省内存空间。

  • 相关阅读:
    Typescript+WebGL+Webpack开发环境搭建
    SVG的动态之美-搜狗地铁图重构散记
    2017年个人总结-程序员的中年焦虑症
    上海2017QCon个人分享总结
    CSS预编译与PostCSS以及Webpack构建CSS综合方案
    前端工程师的基本素养
    不仅仅是复制粘贴
    《微信小程序七日谈》- 第七天:不要捡了芝麻丢了西瓜
    《微信小程序七日谈》- 第六天:小程序devtool隐藏的秘密
    《微信小程序七日谈》- 第五天:你可能要在登录功能上花费大力气
  • 原文地址:https://www.cnblogs.com/littlecarry/p/13050183.html
Copyright © 2020-2023  润新知