美文网首页程序员JAVA
JAVA内部类总结笔记

JAVA内部类总结笔记

作者: 果女郎 | 来源:发表于2018-11-01 17:24 被阅读0次

    内部类分为四类:成员内部类、局部(作用域)内部类、匿名内部类、静态内部类。

    内部类大比拼

    内部类 成员内部类 局部(作用域)内部类 匿名内部类 静态内部类
    访问修饰符

    成员内部类

    就像一个成员变量和方法一样,你说她有没有修饰符?有的呀!同时可以访问外部类的静态/非静态变量和方法。

    若内部类拥有与外部类同名成员(变量/方法),默认访问成员内部类。访问外部 外部类.this.成员(变量/方法)

    综上:想成员一样的成员内部类,使用时需要先创建外部对象。

    public class Outter {
        private Inner inner = null;
     
        public void printMsg() {
            System.out.println("我是一个快乐的外部类");
        }
     
        public class Inner {
     
            public void printMsg() {
                System.out.println("我是一个快乐的内部类");
            }
     
            public void printAgain() {
                this.printMsg();
                Outter.this.printMsg();
            }
        }
     
        /**
         * 听说使用getXXX的方式获取实例对象会更优雅哦
         */
        public Inner getInner() {
            if (null == inner)
                inner = new Inner();
            return inner;
        }
     
        public static void main (String[] args) {
            //创建外部类对象
            Outter outter = new Outter();
            Outter.Inner inner = outter.new Inner();
            Inner inner2 = outter.getInner();
            inner.printMsg();
            inner2.printMsg();
            outter.printMsg();
            inner.printAgain();
        }
    }
    
    打印结果: 成员内部类打印结果

    这是我随手写的一个丑陋的内部类。printAgain写了在内部类调用同名外部类成员的方式。

    局部内部类

    联想一下,局部?局部变量啥的,作用域是局部的。这里的局部内部类是指方法内定义内部类和作用域内定义内部类。她们的访问权限仅限方法/作用域。

    她们有访问修饰符吗?你想想,你家方法内部的变量写访问修饰符了吗?小傻瓜。

    public class Outter {
        private MemberInner inner = null;
     
        public void printMsg() {
            System.out.println("Outter.printMsg: 我是一个快乐的外部类");
        }
     
        /**
         * 成员内部类
         */
        public class MemberInner {
     
            public void printMsg() {
                System.out.println("Inner.printMsg: 我是一个快乐的内部类");
            }
     
            public void printAgain() {
                //他自己
                this.printMsg();
                //他外面的
                Outter.this.printMsg();
            }
        }
     
        /**
         * 听说使用getXXX的方式获取实例对象会更优雅哦
         */
        public MemberInner getInner() {
            if (null == inner)
                inner = new MemberInner();
            return inner;
        }
     
        public MemberInner ordinaryMethod() {
            /**
            *局部内部类-方法内
            */
             class LocalInner extends MemberInner{
                 @Override
                public void printMsg() {
                    System.out.println("LocalInner.printMsg: 人家才不是成员内部类呢,我是一个可爱的方法内局部内部类啊!");
                }
            }
            return new LocalInner();
        }
     
        public void anotherOrdinaryMethod (Boolean isTrue) {
            if (isTrue) {
                /**
                *局部内部类-作用域
                */
                class AnotherLocalInner {
                    public void printMsg() {
                        System.out.println("AnotherLocalInner.printMsg: 我是一个可爱的作用域内部类啊!");
                    }
                }
                this.printMsg();
                printMsg();
                new AnotherLocalInner().printMsg();
     
            }
        }
     
        public static void main (String[] args) {
            //创建外部类对象
            Outter outter = new Outter();
     
            //成员内部类
            Outter.MemberInner inner = outter.new MemberInner();
            MemberInner inner2 = outter.getInner();
            inner.printMsg();
            inner2.printMsg();
            outter.printMsg();
            inner.printAgain();
            System.out.println("----------------------华丽丽的分割线---------------------");
            //局部内部类
            outter.ordinaryMethod().printMsg();
            outter.anotherOrdinaryMethod(true);
        }
    }
    

    打印结果:

    Inner.printMsg: 我是一个快乐的内部类
    Inner.printMsg: 我是一个快乐的内部类
    Outter.printMsg: 我是一个快乐的外部类
    Inner.printMsg: 我是一个快乐的内部类
    Outter.printMsg: 我是一个快乐的外部类
    ----------------------华丽丽的分割线---------------------
    LocalInner.printMsg: 人家才不是成员内部类呢,我是一个可爱的方法内局部内部类啊!
    Outter.printMsg: 我是一个快乐的外部类
    Outter.printMsg: 我是一个快乐的外部类
    AnotherLocalInner.printMsg: 我是一个可爱的作用域内部类啊!
     
    Process finished with exit code 0
    

    综上:无

    匿名内部类

    感觉大多是用在swing编程,监听事件啊、接口回调什么的。对继承方法的重写或者实现什么的。
    她没有访问修饰符,由于没有名字(类名),可怜得连构造方法也没有QAQ(不能定义构造方法,但有内部代码块来初始化参数)

    public class Outter {
        private MemberInner inner = null;
     
        public void printMsg() {
            System.out.println("Outter.printMsg: 我是一个快乐的外部类");
        }
     
        /**
         * 成员内部类
         */
        public class MemberInner {
     
            public void printMsg() {
                System.out.println("Inner.printMsg: 我是一个快乐的内部类");
            }
     
            public void printAgain() {
                //他自己
                this.printMsg();
                //他外面的
                Outter.this.printMsg();
            }
        }
     
        /**
         * 听说使用getXXX的方式获取实例对象会更优雅哦
         */
        public MemberInner getInner() {
            if (null == inner)
                inner = new MemberInner();
            return inner;
        }
     
        /**
         * 内部类使用了方法的形参age
         */
        public MemberInner ordinaryMethod(int age) {
            /**
            *局部内部类-方法内
            */
             class LocalInner extends MemberInner{
                 @Override
                public void printMsg() {
                     System.out.println("伦家今年" + (age) + "岁呢");
                     System.out.println("LocalInner.printMsg: 人家才不是成员内部类呢,我是一个可爱的方法内局部内部类啊!");
                }
            }
            return new LocalInner();
        }
     
        public void anotherOrdinaryMethod (Boolean isTrue) {
            if (isTrue) {
                /**
                *局部内部类-作用域
                */
                class AnotherLocalInner {
                    public void printMsg() {
                        System.out.println("AnotherLocalInner.printMsg: 我是一个可爱的作用域内部类啊!");
                    }
                }
                this.printMsg();
                printMsg();
                new AnotherLocalInner().printMsg();
     
            }
        }
     
        public void getAnonymousInner(AnonymousInner anonymousInner) {
            System.out.println("这么可爱一定是" + anonymousInner.whatSex() + "吧!");
        }
     
        /**
         * 内部类使用方法形参
         */
        public AnonymousInner transferValue(String sex) {
            return new AnonymousInner() {
                @Override
                public String whatSex() {
                    return sex;
                }
            };
        }
     
        public static void main (String[] args) {
            //创建外部类对象
            Outter outter = new Outter();
     
            //成员内部类
            Outter.MemberInner inner = outter.new MemberInner();
            MemberInner inner2 = outter.getInner();
            inner.printMsg();
            inner2.printMsg();
            outter.printMsg();
            inner.printAgain();
            System.out.println("----------------------华丽丽的分割线---------------------");
            //局部内部类
            outter.ordinaryMethod(12).printMsg();
            outter.anotherOrdinaryMethod(true);
            System.out.println("----------------------华丽丽的分割线---------------------");
            //匿名内部类
            outter.getAnonymousInner(new AnonymousInner() {
                @Override
                public String whatSex() {
                    return "男孩子";
                }
            });
            outter.getAnonymousInner(outter.transferValue("女孩子"));
        }
    }
     
    /**
     * 匿名内部类的抽象类
     */
    abstract class AnonymousInner {
        public abstract String whatSex();
    }
    

    打印结果:

    Inner.printMsg: 我是一个快乐的内部类
    Inner.printMsg: 我是一个快乐的内部类
    Outter.printMsg: 我是一个快乐的外部类
    Inner.printMsg: 我是一个快乐的内部类
    Outter.printMsg: 我是一个快乐的外部类
    ----------------------华丽丽的分割线---------------------
    伦家今年12岁呢
    LocalInner.printMsg: 人家才不是成员内部类呢,我是一个可爱的方法内局部内部类啊!
    Outter.printMsg: 我是一个快乐的外部类
    Outter.printMsg: 我是一个快乐的外部类
    AnotherLocalInner.printMsg: 我是一个可爱的作用域内部类啊!
    ----------------------华丽丽的分割线---------------------
    这么可爱一定是男孩子吧!
    这么可爱一定是女孩子吧!
    

    在方法ordinaryMethod中,使用了外部方法的形参age,在我试图修改age时,ide提示错误:

    Variable 'age' is accessed from within inner class,needs to be final or effectively final
    变量age是在内部类中访问的,需要时final修饰的或是实际上的最终变量。

    在以前内部类相关博文中提到,局部内部类和匿名内部类使用外部类局部变量或形参时必须是final,但在JAVA8中不再必须final了,是effectively final也支持。即只要你不去修改外部局部变量/形参的值,则视为effectively final,就不会报错。

    修改形参
    不修改

    关于JAVA8以前必须使用final修饰的原因:

    首先,一个有内部类的类,在编译器编译时,会将内部类单独编译成一个class文件,即有两个class文件。内部类不是直接使用传递参数,而是通过拷贝备份(利用自身构造器)的方式来使用,所以如果内部类使用的变量和外部方法的变量不是同一个,在内部类中变量发生变化,会造成数据的不一致性,因此用final来限定局部变量和形参的不可变。

    静态内部类

    想一想,不充钱你会变得更强吗?

    想一想,你在用你的工具类的时候需要去new她吗?不。

    所以,不需要外部类先去创建实例对象。因此可以推断,他(静态内部类)也不能使用外部类的非静态成员(变量/方法),因为外部类非静态成员是依赖具体对象的。

    public class AnotherOutter {
        public static class StaticInner {
            public void printMsg() {
                System.out.println("想一想,不充钱?你会变得更强吗?----静态内部类");
            }
        }
     
        public static void main (String[] args) {
            StaticInner staticInner = new StaticInner();
            staticInner.printMsg();
        }
    }
     
    class Strangers {
        public static void main (String[] args) {
            AnotherOutter.StaticInner staticInner = new AnotherOutter.StaticInner();
            staticInner.printMsg();
        }
    }
    

    关于内部类的总结就到这里了,如果有错误的地方欢迎各位指正,谢谢(づ ̄3 ̄)づ╭❤~。。
    作者:90后青壮年 (果女郎)
    来源:CSDN
    原文:https://blog.csdn.net/kiana168/article/details/83617481
    版权声明:本文为博主原创文章,转载请附上博文链接!

    相关文章

      网友评论

        本文标题:JAVA内部类总结笔记

        本文链接:https://www.haomeiwen.com/subject/zrbxxqtx.html