一个类的内部又完整的嵌套了另一个类结构,被嵌套的类称为内部类,嵌套其他类的类称为外部类;
内部类最大的特点就是可以直接访问私有属性,并且可以体现类与类之间的包含关系;
内部类是一个类;
四种内部类:
定义在外部类局部的位置上(比如方法内):
- 局部内部类(有类名);
- 匿名内部类(没有类名,重点);
定义在外部类的成员位置上:
- 成员内部类(没有static修饰);
- 静态内部类(有static修饰);
局部内部类:
- 可以直接访问外部类的所有成员,包含私有的;
- 不能添加访问修饰符,因为它的地位就是一个局部变量,局部变量不能使用修饰符。但是可以使用final修饰,因为局部变量也可以使用final;
- 作用域:仅仅在定义它的方法或代码块中;
- 局部内部–访问–>外部类的成员,访问方式:直接访问;
- 外部类–访问–>局部内部类的成员,访问方式:创建对象后再访问,但必须在作用域内;
- 外部其他–不能访问–>局部内部类,因为局部内部类的地位是一个局部变量;
- 如果外部类和局部内部类的成员重名时,默认遵守就近原则,如果想访问外部类的成员可以使用(外部类名.this.成员)去访问(外部类名.this相当于一个对象,这个对象具体指向调用了这个含有这个内部类的对象);
匿名内部类:
- 匿名内部类同时还是一个对象;
- 匿名内部类没有名字,但是系统为它分配了隐含的名字;
- 基于接口/类的匿名内部类编译类型是接口/类,但运行类型是匿名内部类(其实在系统底层系统创建了一个由系统分配名字的实现了接口的类,名字就是外部类名后加上$1,使用过后该类自动销毁);
- jdk底层在创建了匿名内部类后,立即就创建了一个该类的对象并返回该对象实例的地址;
- 匿名内部类创建后只能使用一次,就不能再使用了;
- 创建基于抽象类的匿名内部类需要实现抽象类的抽象方法;
- 基于类的匿名内部类,形参列表会传递给构造器;
- 外部其他类–不能访问–>匿名局部内部类,因为它的地位是一个局部变量;
- 如果外部类和匿名内部类的成员重名时,默认遵守就近原则,如果想访问外部类的成员可以使用(外部类名.this.成员)去访问(外部类名.this相当于一个对象,这个对象具体指向调用了这个含有这个内部类的对象);
- 匿名内部类可以当作参数直接传递给形参,因为它也是一个对象;
- 匿名内部类重点:继承,多态,动态绑定,内部类;
成员内部类:
- 定义在外部类的成员位置,并且没有static修饰;
- 可以直接访问外部类的所有成员,包含私有的;
- 可以使用任意的访问修饰符,因为它的地位就是一个成员;
- 作用域和其他外部成员一样,是整个类,因为它就是一个成员,在外部的成员方法中创建内部类对象,再调用方法;
外部其它类访问成员内部类的两种方式:
- 在外部类中编写一个方法,返回一个成员内部类的实例对象;
- 通过一个外部类的对象来直接new一个成员内部类的对象;
如果外部类和成员内部类的成员重名时,默认遵守就近原则,如果想访问外部类的成员可以使用(外部类名.this.成员)去访问;
静态内部类:
- 定义在外部类的成员位置,并且有static修饰;
- 可以直接访问外部类的所有静态成员,包含私有的,但是不能直接访问非静态成员;
- 可以使用任意的访问修饰符,因为它的地位就是一个成员;
- 作用域和其他外部成员一样,是整个类,因为它就是一个成员,在外部的成员方法中创建内部类对象,再调用方法;
外部其它类访问静态内部类的两种方式:
- 通过外部类的类名来直接访问(前提是要有访问权限),因为它是静态的;
- 在外部类中编写一个方法,返回一个静态内部类的实例对象;
如果外部类和成员内部类的成员重名时,默认遵守就近原则,如果想访问外部类的成员可以使用(外部类名.成员)去访问