Java内部类详解

一、前言

内部类指的是在一个类的内部定义一个类,主要有四种:成员内部类、局部内部类、匿名内部类以及静态内部类。以下通过具体代码对四种内部类做一个介绍

 

二、成员内部类

成员内部类的定义位于另一个类的内部。成员内部类可以无条件访问外部类的所有成员属性和成员方法(包括private成员和静态成员)。

package com.wsh;

/**
 * Created by weishihuai on 2018/9/16.
 * 测试成员内部类访问外部类的属性以及方法
 * 说明:
 * 1. 成员内部类可以无条件访问外部类的属性以及方法
 * 2. 成员内部类访问与外部类同名属性的时候需要加上外部类.this才能获取外部类中同名属性的值
 * 3. 创建一个成员内部类对象必须先创建一个外部类的对象,在通过外部类对象.new 内部类()方式创建
 *
 * @author: weishihuai
 * @date: 2018-09-16 20:59
 */
public class OuterClass {
    /**
     * 私有属性
     */
    private String name = "weixiaohuai";

    int age = 18;

    /**
     * 静态属性
     */
    static String hobby = "basketball";

    String say() {
        return "外部类方法";
    }

    String string = "outerString";

    class InnerClass {
        String string = "innerString";

        /**
         * 访问外部类属性
         */
        public void accessOuterClassProperty() {
            System.out.println("访问外部类中的私有属性>>>>" + name);
            System.out.println("访问外部类中的普通属性>>>>" + age);
            System.out.println("访问外部类中的静态属性>>>>" + hobby);
            System.out.println("访问外部类中的方法>>>>" + say());

            //注意,如果外部类跟内部类有相同名字的属性,在内部类直接访问是取的内部类的属性,如果需要访问外部类的同名属性则需要加上外部类.this.属性名称
            //注意没加外部类.this
            System.out.println("访问外部类的同名属性>>>>" + string);
            System.out.println("访问外部类的同名属性>>>>" + OuterClass.this.string);

        }
    }

    public static void main(String[] args) {
        //创建内部类对象的方法
        //必须要先有外部类对象,才能创建内部类对象
        OuterClass outerClass = new OuterClass();
        InnerClass innerClass = outerClass.new InnerClass();
        innerClass.accessOuterClassProperty();
    }

}

Java内部类详解_第1张图片

可以看到控制台输出,说明内部类可以无条件访问外部的属性以及方法,下面我们讲解以下外部类访问内部类的属性以及方法:

/**
 * Created by weishihuai on 2018/9/16.
 * 测试外部类访问内部类属性以及方法
 * 说明:
 * 1. 外部类如果需要访问内部类的属性或者方法,那么必须先创建一个内部类对象,再通过指向这个对象的引用访问内部类属性以及方法
 * 2. 成员内部类里面不能有static的变量或者方法
 *
 * @author: weishihuai
 * @date: 2018-09-16 21:33
 */
public class OuterClass2 {

    void say() {
        System.out.print("外部类访问内部类的方法>>>>>");
        System.out.println(new InnerClass().say());
        System.out.print("外部类访问内部类的属性>>>>>");
        System.out.println(new InnerClass().name);
    }


    class InnerClass {
        private String name = "weixiaohuai";
        
        public String say() {
            return "InnerClass>>>>>say()方法";
        }

    }

    public static void main(String[] args) {
        OuterClass2 outerClass2 = new OuterClass2();
        outerClass2.say();
    }

}

Java内部类详解_第2张图片

从控制台可以看到,外部类也可以访问内部类的方法以及属性。

三、局部内部类

局部内部类是定义在一个方法或者一个作用域里面的类,它和成员内部类的区别在于局部内部类的访问仅限于方法内或者该作用域内。

局部内部类在实际工作中基本上不会用到,所以做个了解即可。

/**
 * Created by weishihuai on 2018/9/16.
 * 测试局部内部类
 * 说明: 实际工作中,基本不会用到
 *
 * @author: weishihuai
 * @date: 2018-09-16 21:44
 */
public class LocalInnerClass {

    public void say() {
        //在方法里面创建一个局部内部类
        class InnerClass {
            public void say() {
                System.out.println("say()");
            }
        }
    }

}

四、匿名内部类

一般使用匿名内部类的方法来编写事件监听代码。匿名内部类是不能有访问修饰符和static修饰符的。

/**
 * Created by weishihuai on 2018/9/16.
 * 测试匿名内部类
 * 说明: 实际工作中匿名内部类用的比较多,在注册事件或者创建线程时就可以使用匿名内部的方式
 * 本文以创建线程的方式做讲解
 *
 * @author: weishihuai
 * @date: 2018-09-16 21:51
 */
public class AnonymousInnerClass {

    public static void main(String[] args) {
        new Thread(new Runnable() {
            @Override
            public void run() {
                System.out.println("使用匿名内部类的方式创建线程");
            }
        });
    }

}

五、静态内部类

静态内部类就是在成员内部类的基础上多了一个static关键字修饰,静态内部类不需要依赖外部类对象存在,静态内部类不能访问外部类中非静态属性和方法,只能访问静态属性以及方法,原因: 因为创建静态内部类的对象之前可以不需要创建外部类对象,所以如果创建内部类对象的时候还没有创建外部类对象,这时候访问外部类属性或者方法就会报错。

/**
 * Created by weishihuai on 2018/9/16.
 * 测试静态内部类
 * 说明:
 * 1. 静态内部类只能访问外部类中静态属性以及方法
 * 2. 静态内部类不能访问外部类中非静态属性以及方法
 * 原因:  因为创建静态内部类的对象之前可以不需要创建外部类对象,所以如果创建内部类对象的时候还没有创建外部类对象,这时候访问外部类属性或者方法就会报错。
 * 3. 静态内部类对象的创建不需要依附外部对象的创建,可以在没有创建外部类对象之前就创建静态内部类对象
 *
 * @author: weishihuai
 * @date: 2018-09-16 21:58
 */
public class StaticInnerClass {

    private String string = "string";
    private static String string1 = "static string";

    private void say() {
        System.out.println("say()");
    }

    private static void say2() {
        System.out.println("static say2()");
    }

    static class InnerClasss {

        void innerSay() {
            //下面一行代码报错:静态内部类只能访问外部类静态属性
//             System.out.println(string);
            System.out.println(string1);
            //下面一行代码报错:静态内部类只能访问外部类静态方法
//            say();
            say2();
        }

    }

    public static void main(String[] args) {
        InnerClasss innerClasss = new InnerClasss();
        innerClasss.innerSay();
    }

}

Java内部类详解_第3张图片

由上图可见,内部类不能访问外部类中非静态属性,会报错。但是可以访问外部类中static修饰的属性或者方法,如下图:

Java内部类详解_第4张图片

同样,外部类可以访问到静态内部类中的属性或者方法:

public class StaticInnerClass {
    private static void say2() {
        System.out.println("外部类可以访问到内部类的私有属性>>>" + new InnerClasss().name);
        System.out.println("外部类可以访问到内部类的静态属性>>>" + InnerClasss.age);
        new InnerClasss().test();
    }

    static class InnerClasss {

        private String name = "weixiaohuai";
        static int age = 20;

        void test() {
            System.out.println("外部类可以访问内部类的属性或者方法");
        }

    }

    public static void main(String[] args) {
        StaticInnerClass.say2();
    }

}

运行结果:

Java内部类详解_第5张图片

以上就是关于内部类的一些讲解。

你可能感兴趣的:(java,内部类,java,静态内部类,java,成员内部类,java,匿名内部类,Java后端)