• java中的内部类


    java中很重要的一个知识点是内部类,经常会用到,参考百度百科整理如下:

    内部类分为:成员内部类、静态内部类、方法内部类、匿名内部类。

    内部类的特点:

    1、内部类任然是一个独立的类,编译后内部类会被编译成独立的.class文件,前面冠以外部类名和$符号;
    2、内部类是外部类的一个成员,因此可以自由地访问外部类的成员变量,无论是否是private类型的;
    3、内部类声明为静态的,就不能随便访问外部类的成员变量了,只能访问外部类的静态成员变量。

    一、成员内部类

    1、内部类一般形式

    public class Out {
    
        private int age = 18;
    
        public class In {
            public void printAge() {
                System.out.println(age);
            }
        }
    
        /**
         * @param args
         */
        public static void main(String[] args) {
            // TODO Auto-generated method stub
            Out.In in = new Out().new In();
            in.printAge();
            /*下面写法也可以
            Out out=new Out();
            Out.In in=out.new In();
            in.printAge();
            */
        }
    
    }

    上面程序输出结果:18

    说明内部类可以访问外部类的private类型变量;两种实例化内部类的方式,而且实例化内部类之前需要创建外部类对象;查看编译后的.class文件,发现有两个,Out.class和Out$In.class。

    2、同名变量的作用域

    public class Out {
    
        private int age = 18;
    
        public class In {
            private int age = 19;
    
            public void printAge() {
                int age = 20;
                System.out.println("局部变量:" + age);
                System.out.println("内部类变量:" + this.age);
                System.out.println("外部类变量:" + Out.this.age);
            }
        }
    
        /**
         * @param args
         */
        public static void main(String[] args) {
            // TODO Auto-generated method stub
            Out.In in = new Out().new In();
            in.printAge();
            /*
             * 下面写法也可以 Out out=new Out(); Out.In in=out.new In(); in.printAge();
             */
        }
    
    }

    局部变量、内部类变量和外部类变量同名的话会覆盖掉,调用内部和外部类变量时要用this.属性名和Out.this.属性名。

    3、私有内部类

    public class Out {
    
        private int age = 18;
    
        private class In {
            public void printAge() {
                System.out.println(age);
            }
        }
    
        public void outPrint() {
            new In().printAge();
        }
    
        /**
         * @param args
         */
        public static void main(String[] args) {
            // TODO Auto-generated method stub
            // Out out = new Out();
            // out.outPrint();
            Out.In in = new Out().new In();
            in.printAge();
        }
    
    }

    程序输出:18

    二、静态内部类

    public class Out {
    
        private static int age = 18;
    
        static class In {
            public void printAge() {
                System.out.println(age);
            }
        }
    
        /**
         * @param args
         */
        public static void main(String[] args) {
            // TODO Auto-generated method stub
            // Out out = new Out();
            // out.outPrint();
            Out.In in = new Out.In();
            in.printAge();
        }
    
    }

    静态内部类只能访问外部类的静态变量,而且可以不用实例化外部类就可以创建外部类的对象。

    三、方法内部类

    public class Out {
    
        private int age = 18;
    
        public void print() {
            final int a = 12;// 方法内部类只能访问方法中的final类型变量
            class In {
                public void printAge() {
                    System.out.println(a);
                    System.out.println(age);
                }
            }
            new In().printAge();
        }
    
        /**
         * @param args
         */
        public static void main(String[] args) {
            // TODO Auto-generated method stub
            Out out = new Out();
            out.print();
        }
    
    }

    因为方法的局部变量位于栈上,只存在于函数的生命周期中,内部类位于堆上,它们的生命周期不一样,所以方法内部类不能访问方法中的非final类型变量。

    四、匿名内部类

    顾名思义,没有名字的内部类。表面上看起来它们似乎有名字,实际那不是它们的名字。
    匿名内部类就是没有名字的内部类。什么情况下需要使用匿名内部类?如果满足下面的一些条件,使用匿名内部类是比较合适的:
    ·只用到类的一个实例 。
    ·类在定义后马上用到。
    ·类非常小(SUN推荐是在4行代码以下)
    ·给类命名并不会导致你的代码更容易被理解。
    在使用匿名内部类时,要记住以下几个原则:
    ·匿名内部类不能有构造方法。
    ·匿名内部类不能定义任何静态成员、静态方法。
    ·匿名内部类不能是public,protected,private,static。
    ·只能创建匿名内部类的一个实例。
    ·一个匿名内部类一定是在new的后面,用其隐含实现一个接口或实现一个类。
    ·因匿名内部类为局部内部类,所以局部内部类的所有限制都对其生效。

    1、继承式的匿名内部类
    public class Out {
    
        public void drive(){
            System.out.println("Driving a car!");
        }
        
        /**
         * @param args
         */
        public static void main(String[] args) {
            // TODO Auto-generated method stub
            Out out = new Out(){
                public void drive(){
                    System.out.println("Driving another car!");
                }
            };
            out.drive();
        }
    
    }
    
    2、接口式的匿名内部类
    public class Out {
    
        interface Car{
            public void drive();
        }
        
        /**
         * @param args
         */
        public static void main(String[] args) {
            // TODO Auto-generated method stub
            Car car = new Car(){
                public void drive(){
                    System.out.println("Driving a car!");
                }
            };
            car.drive();
        }
    
    }
    
    3、参数式的匿名内部类
    public class Out {
    
        void doStuff(Foo f){
            f.foo();
        }
        interface Foo{
            public void foo();
        }
        
        /**
         * @param args
         */
        public static void main(String[] args) {
            // TODO Auto-generated method stub
            Out out = new Out();
            out.doStuff(new Foo(){
                public void foo(){
                    System.out.println("hello");
                }
            });
        }
    
    }

    与君共勉。

  • 相关阅读:
    第一次个人编程作业:我的分数我做主
    第一次作业
    finalshell编码问题
    个人总结-超越平台期
    第一次结对作业
    第二次编程作业代码互改
    第一次个人编程作业
    随笔001
    热是热,很值得—-2019北航暑期软件工程培训感受
    培训第二天------团队协作个人小结
  • 原文地址:https://www.cnblogs.com/nannanITeye/p/3562456.html
Copyright © 2020-2023  润新知