zoukankan      html  css  js  c++  java
  • java中的内部类

    一、成员内部类

    package cd.itcast.test;
    /*
     *  1、Inner 类中定义的 test() 方法可以直接访问 Outer 类中的数据,
     *      而不受访问控制符的影响,如直接访问 Outer 类中的私有属性a。
     *  2、定义了成员内部类后,必须使用外部类对象来创建内部类对象,而不能
     *      直接去 new 一个内部类对象,即:内部类 对象名 = 外部类对象.new 内部类( )。
     *  3、编译上面的程序后,会发现产生了两个 .class 文件:Outer.class和Outer$Inner.class文件
     *  注意:
     *  1、外部类不能直接使用内部类的成员和方法。如果使用可创建内部类的对象来访问。
     *  2、外部类和内部类具有相同的成员变量或方法。内部类默认访问自己的变量或方法。
     */
    public class Outer {
        private int a = 99;
        private int b = 55;
        //内部类
        public class Inner{
            int b = 88;
            public void test() {
                //内部类可以直接访问外部成员变量
                System.out.println("外部类变量a:"+ a);
                //2、外部类和内部类具有相同的成员变量或方法。内部类默认访问自己的变量或方法。
                System.out.println("访问外部同名的变量b:"+ Outer.this.b);
                System.out.println("内部类变量b:"+ b);
            }
        }
        public static void main(String[] args) {
            Outer o = new Outer();
            //注意内部类的创建方式
            Inner i= o.new Inner();
            i.test();
        }
    }

    二、静态内部类

    package cd.itcast.test;
    /*
     * 1、 静态内部类不能直接访问外部类的非静态成员,但可以通过 new 外部类().成员 的方式访问 
     * 2、 如果外部类的静态成员与内部类的成员名称相同,可通过“类名.静态成员”访问外部类的静态成员;
     *         如果外部类的静态成员与内部类的成员名称不相同,则可通过“成员名”直接调用外部类的静态成员
     * 3、 创建静态内部类的对象时,不需要外部类的对象,可以直接创建 内部类 对象名= new 内部类();
     */
    public class SOuter {
        //外部私有变量
        private int a = 99;
        //外部静态变量
        static int b = 55;
        public static class SInner{
            int b = 66;
            public void test() {
                System.out.println("访问外部同名成员b:"+SOuter.b);
                System.out.println("访问内部类中的b:"+ b);
            }
        }
        
        public static void main(String[] args) {
            //静态内部类,直接创建
            SInner siInner=new SInner();
            siInner.test();
        }
    }

    三、方法内部类:就是在外部类的方法中定义内部类;只在该方法中可以使用。

    package cd.itcast.test;
    /*
     * 
     */
    public class FOuter {
        private void show() {
            final int a = 25;//常量
            int b= 13;
            /*方法内部类:由于方法内部类不能在外部类的方法以外的地方使用,因此方法
            内部类不能使用访问控制符和 static 修饰符。*/
            class FInner{
                int c = 2;
                public void test() {
                    System.out.println("访问外部类方法中的常量a:"+ a);
                    System.out.println("访问内部类的变量c"+ c);
                }
            }
            //创建该类的对象:只能在本方法中创建
            FInner fi = new FInner();
            fi.test();
        }
        
        public static void main(String[] args) {
            FOuter fo = new FOuter();
            fo.show();
        }
    }

     四、匿名内部类

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

      正因为没有名字,所以匿名内部类只能使用一次,它通常用来简化代码编写

      但使用匿名内部类还有个前提条件:必须继承一个父类或实现一个接口。

    实例1:不使用匿名内部类来实现抽象方法

    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类,然后实现了Child的一个实例,将其向上转型为Person类的引用

    但是,如果此处的Child类只使用一次,那么将其编写为独立的一个类岂不是很麻烦?这个时候就引入了匿名内部类

    实例2:匿名内部类的基本实现

    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中的方法在大括号中实现了

      这样便可以省略一个类的书写

      并且,匿名内部类还能用于接口上

    实例3:在接口上使用匿名内部类

    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

      由上面的例子可以看出,只要一个类是抽象的或是一个接口,那么其子类中的方法都可以使用匿名内部类来实现

      最常用的情况就是在多线程的实现上,因为要实现多线程必须继承Thread类或是继承Runnable接口

    实例4: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

  • 相关阅读:
    细节回顾 p标签的嵌套问题
    面向对象编程
    深浅拷贝
    数据交互 jsonp插件
    数据交互 跨域问题
    数据交互 axios
    数据交互 jQuery ajax
    数据交互 后端代码
    数据交互 http请求 xhr
    Windows安装Node.js报错:2503、2502的解决方法
  • 原文地址:https://www.cnblogs.com/h-g-f-s123/p/6128773.html
Copyright © 2011-2022 走看看