zoukankan      html  css  js  c++  java
  • 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、运行一次,直接就被回收掉了,节省内存空间。

  • 相关阅读:
    Oracle函数如何把符串装换为小写的格式
    Oralce中的synonym同义词
    JS中getYear()的兼容问题
    How to do SSH Tunneling (Port Forwarding)
    所谓深度链接(Deep linking)
    upload size of asp.net
    发一个自动刷网站PV流量的小工具
    解决Visual Studio 2008 下,打开.dbml(LINQ) 文件时,提示"The operation could not be completed." 的问题。
    在资源管理器中使鼠标右键增加一个命令,运行cmd,同时使得当前路径为资源管理器当前的目录
    使用SQL语句获取Sql Server数据库的版本
  • 原文地址:https://www.cnblogs.com/littlecarry/p/13050183.html
Copyright © 2011-2022 走看看