zoukankan      html  css  js  c++  java
  • 【Java】InnerClass 内部类

    Java 允许一个类的定义位于另一个类的内部,前者为内部类,后者称为外部类

    InnerClass一般定义它的类或语句块之中外部类引用时必须给出完整的名称

    成员内部类  &  局部内部类

    - 静态成员 内部类

    - 非静态成员 内部类

    - 匿名内部类

    静态内部类  成员内部类  局部内部类

    // 相对于内部类而言,这是一个外部类
    public class OuterClass {
        public int a;
        int b;
        protected int c;
        private int d;
    
        static int e;
        
        public void memberMethod(){
            System.out.println("外部类的成员方法!");
    
            // 成员内部类可以创建实例
            InnerClass innerClass = new InnerClass();
            // 静态内部类可以创建实例
            StaticInnerClass staticInnerClass = new StaticInnerClass();
        }
    
        public static void staticMethod(){
            System.out.println("外部类的静态方法!");
        }
    
        // 成员内部类和静态内部类 都可以abstract抽象 或者final,都可以被4种权限访问修饰
    
        // 成员内部类 不允许任何静态存在
        class InnerClass{
            // 成员内部类可以修饰所有访问权限
            public int a;
            int b;
            protected int c;
            private int d;
    
            // 成员内部类不能写静态方法
            // static void staticMethod(){}
    
            // 成员内部类可以声明成员方法
            void memberMethod(){
                // 成员内部类可以调用外部类的成员方法
                OuterClass.this.memberMethod();
    
                // 成员内部类外部类的静态方法也能被调用
                OuterClass.staticMethod();
            }
    
            // 成员内部类可以构造器
            InnerClass(){}
    
            // 各个字段的访问
            public void checkField(int a){
                // 形参的a
                a = 50;
                // 本成员内部类的字段a
                this.a = 100;
                // 外部类的字段a
                OuterClass.this.a = 150;
            }
        }
    
        // 静态内部类
        static class StaticInnerClass{
            // 静态内部类可以修饰所有访问权限
            public int a;
            int b;
            protected int c;
            private int d;
    
            // 静态内部类可以声明成员方法
            void memberMethod(){
                // 可以调用外部类的静态方法
                OuterClass.staticMethod();
    
                // 外部类的成员方法不行
                // OuterClass.this.memberMethod();
            }
    
            // 静态内部类可以声明静态方法
            static void staticMethod(){
                // 可以调用外部类的静态方法
                OuterClass.staticMethod();
    
                // 外部类的成员方法不行
                // OuterClass.this.memberMethod();
            }
    
            public void fieldCheck(int a){
                // 形参字段
                a = 100;
    
                // 静态内部类的字段
                this.a = 150;
    
                // 外部类字段 只能访问静态方法和静态字段
                OuterClass.e = 300;
            }
    
            // 静态内部类也可以构造器
            StaticInnerClass(){}
        }
    
        public void classMethod(){
            // 局部内部类 没有权限访问修饰,只做用在这个方法之内 ,可以设置final修饰局部内部类
    
            // 被内部类所访问的局部变量必须是Final的
            // x的作用域之存活于这个方法中
            // 当方法调用结束,方法出栈,x变量即被销毁掉
            final int x = 123;
            
            // 局部内部类
            class LocalInnerClass{
    
                // 但是局部内部类的实例依然才在,依然保持这个x变量的引用指向
                // 如果在局部方法被销毁后调用这个方法,就无法再访问这个x变量,这就是BUG问题
                // 但是在JDK8已经默认隐式的表示这个x变量是final修饰的,x必须是一个常量的存在
                // 即表示如果x被销毁,但其值不发生变化,依然是可以被访问赋予的
                
                // 这个原因在于 局部内部类的实例的作用域大于了这个变量的作用域
                public int returnX(){
                    // x += 100; x变量不能被修改
                    return x;
                }
            }
        }
        
        // 局部内部类的用法,可以用于返回一个实现某接口的实例出来
        public Comparable getComparable(){
            class LocalInnerClass implements Comparable{
                // 局部内部类重写接口方法
                @Override
                public int compareTo(Object o) {
                    return 0;
                }
            }
            // 返回给外部调用
            return new LocalInnerClass();
        }
    }
    三个内部类

    静态内部类 和 成员内部类在外部的实例创建与访问

    public class ClassTest {
        public static void main(String[] args) {
            //  实例化静态内部类
            OuterClass.StaticInnerClass staticInnerClass = new OuterClass.StaticInnerClass();
            //  静态内部类的成员方法
            staticInnerClass.memberMethod();
            //  静态内部类的静态方法
            OuterClass.StaticInnerClass.staticMethod();
    
            //  实例化成员内部类,必须要有外部类的实例才可以
            OuterClass outerClass = new OuterClass(); //先创建外部实例
            OuterClass.InnerClass innerClass = outerClass.new InnerClass(); //再通过外部实例调用内部初始化
            //  也可以直接匿名外部类对象,调用内部类初始化
            OuterClass.InnerClass innerClass2 = new OuterClass().new InnerClass();
    
            // 成员内部类调用成员方法
            innerClass.memberMethod();
        }
    }
    实例化与访问

    匿名内部类

    public class ClassTest {
        public static void main(String[] args) {
            
            AnonymousInnerClass anonymousInnerClass = new AnonymousInnerClass() {
                // 这就是匿名内部类的类体,匿名,顾名思义,没有类的名字
                
                // 重写接口的方法
                @Override
                public void aicMethod() {
                    System.out.println("这就是匿名内部类");    
                }
                
                // 匿名内部类只能声明这一次,不能像显示的类一样保存下来
                // 用于创建去实现一个接口或者继承一个抽象类,或者继承普通类也可以
                // 适用于实现只有一个方法的接口,例如多线程的Runnable
                
                // 注意线程还有一个Callable可以使用
            };
        }
    }
    
    // 声明一个接口和一个抽象方法
    interface AnonymousInnerClass{
        void aicMethod();
    }
    匿名内部类
  • 相关阅读:
    【转】Google 的眼光
    【转】不要去SeaWorld
    【转】Tesla Autopilot
    【转】Tesla Model X的车门设计问题
    【转】Tesla Model S的设计失误
    【转】编程的智慧
    【转】智商的圈套
    【转】创造者的思维方式
    【转】恶评《星际穿越》
    【转】谈创新
  • 原文地址:https://www.cnblogs.com/mindzone/p/12724933.html
Copyright © 2011-2022 走看看