Java | 内部类

内部类

什么是内部类

内部类就是在一个类内部进行其它类结构的嵌套操作。

定义一个内部类

public class TestClass {
    //成员变量
    private String id;

    //成员方法
    public void test() {
        System.out.println("成员方法");
    }
    
    //内部类
    class OnClass{
        //内部类里面的方法
        public int id;
        //内部类里面的方法
        public void OnMethod(){
            System.out.println("内部类");
        }
    }
}

内部类的作用

1、内部类提供了更好的封装,只能让外部类直接访问,不允许同一个包中的基他类直接访问。
2、内部类可心直接访问外部类的私有属性,内部类被当成其外部类的成员,但外部类不能直接访问内部类的内部属性。

内部类的使用场合

由于内部类提供了更好的封装特性,并且可以很方便的访问外部类的属性,所以,通常内部类在只为所在外部类提供服务的情况下优先使用。

内部类的使用

成员内部类

内部类就象是外部类的成员一样。(可以使用private,proteted,public 任意进行修饰,生成的类文件是:外部类$内部类.class)

非静态内部类

成员内部类也是最普通的内部类,它是外围类的一个成员,所以他是可以无限制的访问外围类的所有的成员变量和方法的,但是外部类访问内部的属性和方法的时候,必须要实例化一下内部类。
在非静态内部类里面不能有静态方法、静态属性、静态代码块的存在。

public class TestClass {
    //成员变量
    private int id =2;
    private String name = "外部类属性";
    private static int age = 18;

    //成员方法
    public void test() {
        System.out.println("外部类里面的成员方法");
    }

    //内部类
    class OnClass{
        //内部类里面的方法
        public int id = 1;
        //内部类里面的方法
        public void OnMethod(){
            //这个地方使用的是部内类里面的id
            System.out.println("使用内部类里面的变量:" + this.id);
            //如果想要使用外部类里面的id
            System.out.println("使用外部类里面的变量:" + TestClass.this.id);
            //如果没有重名的情况下可以直接使用外部类里面的变量或者方法
            System.out.println("使用外部类里面的不重名的属性:" + name);
            //也可以直接使用外部类里面的静态方法
            System.out.println("使用外部类里面的成员方法:" + age);
            //也可以使用直接使用外部类里面同的方法
            test();
            /*  运行的结果:
                使用外部类里面的变量:2
                使用外部类里面的不重名的属性:外部类属性
                使用外部类里面的成员方法:18
                外部类里面的成员方法
             */
        }
    }
}
class TestUser{
    public static void main(String[] args) {
        //创建一个外部类对象
        TestClass testClass = new TestClass();
        //创建一个内部类对象
        TestClass.OnClass onClass = testClass.new OnClass();
        onClass.OnMethod();
    }
}

生成的.class文件

第一个文件就是内部类的文件,其实内部类只是在编译的时候,有逻辑上面的关系,但是运行的时候,还是一个独立的类。

静态内部类

我们知道用static可以修饰方法,变量,代码块,其实还可心修饰内部类,在使用static修饰的内部类我们称之为静态内部类。
;静态内部类里面不可以引用外部类非静态的方法或者变量,静态的都可以引用。
静态内部类创建的时候可以不依靠外部来来创建,可以直接实例化。这是因为非静态内部类在编译完成成之后会隐含地保存着一个外部类的引用,这个引用是指向外围的,但是静态内部类没有。所以可心单独实例化。

public class TestStaticClass {
    private int id = 1;
    private static String name = "外部类成员变量";

    public void test1() {
        System.out.println("外部非静态方法");
    }

    public static void test2() {
        System.out.println("外部静态方法");
    }

    /*
    定义一个静态内部类
     */
    static class OnStaticClass{
        public void onTest() {
            System.out.println("引用外部类静态变量:" + name);
            //System.out.println("引用外部类非静态变量:" + id); 不可以使用非静态的方法和变量
            test2();    //可以使用静态的方法,
            //test1();  //不可以使用非静态的方法
            /* 运行的结果:
                引用外部类静态变量:外部类成员变量
                外部静态方法
             */
        }
    }
}
class Test{
    public static void main(String[] args) {
        //创建一个静态内部类方法不需要要依靠外部类
        TestStaticClass.OnStaticClass onStaticClass = new TestStaticClass.OnStaticClass();
        onStaticClass.onTest();
    }
}

局部内部类

局部内部类是作用于方法内和作用域内的,这个类是用来解决非常复杂的问题,但是又不想别的类来调用他,所以就有了局部内部类了。这个类的作用域就是在该方法内或者作用域内。
局部内部类不允许使用权限修饰符号。

public class TestMethodClass {
    //创建一个方法
    public String test(String name) {
        /*
        在方法里面创建一个局部内部类,作用是给name加上一名句话
         */
        class addString {
            public String resName(String name) {
                return name + "使用局部内部类";
            }
        }
        //最后返回
        return new addString().resName(name);
    }

    public static void main(String[] args) {
        //创建一个本类对象
        TestMethodClass testMethodClass = new TestMethodClass();
        //调用方法,得到结果,并打印
        String mainName = testMethodClass.test("张三");
        System.out.println(mainName);
        //输出的结果:张三使用局部内部类
    }
}

生成的类文件

生成的类文件里面格式是 外部类名$x内部类名.class。x的数值是随机的。

匿名内部类

适用于那种只需要使用一次的类。匿名内部类也是我们使用次数最多的一个内部类,匿名内部类的特点:

  • 匿名内部类必须继承一个抽象类或者实现一个接口,并且里面都是只有一个抽象方法。
  • 匿名内部类是没有访问修饰符号的。
  • 匿名内部类没有类名,所以也就没有构造方法,
public class Anonymous {
    //定义一个方法来使用匿名内部类
    public String testAnonymous() {
        //直接使用匿名内部类来返回
        return new TestAnonymous() {

            @Override
            public String getName() {
                return "张三";
            }
        }.getName();
    }
    /*
    主方法
     */
    public static void main(String[] args) {
        Anonymous anonymous = new Anonymous();
        String name = anonymous.testAnonymous();
        System.out.println("从匿名内部类里面得到的姓名 :"+name);
        //输出的结果:从匿名内部类里面得到的姓名 :张三
    }
}
/*
定义一个接口用来使用匿名内部类
 */
interface TestAnonymous{
    String getName();
}

生成类的文件

第一个文件就是匿名内部类的文件,在$后的是匿名内部类的文件名,这是因为匿名内部类没有类名,所以这个数字是随机的。



关注公众号,随时获取最新资讯

细节决定成败!
个人愚见,如有不对,恳请斧正!

posted @ 2020-03-26 14:19  一点浩然气~  阅读(214)  评论(0编辑  收藏  举报