内部类:


a、定义在其他类内部的类称为内部类,包含内部类的类称为外部类。


b、内部类可以比外部类多使用三个修饰符:private、protected、static。


c、编译一个含有内部类的外部类Java文件时,会生成两个 class 文件,一个是 Outter.class、一个是 Outter&Innter.class 文件。


d、内部类分为成员内部类,局部内部类,静态内部类,匿名内部类。



成员内部类:


成员内部类定义在外部类内部,位置和成员变量类似,如下:




java外部类定义 java内部类和外部类的区别_外部类



a、外部类的上一级程序单元是包,所以它的作用域只有两个:包内和任何位置。因此访问权限有两个:包内访问和公开访问,对应省略访问控制符和 public 访问控制符。而内部类的上一级程序单元是外部类,类似于类的一个变量,所以它具有四个作用域:同一个类、父子类、同一个包和任何位置,因此有四种访问权限。


b、成员内部类可以直接访问外部类的 private 成员,这是因为在成员内部类对象里保存了一个它所寄生的外部类对象的引用(当调用成员内部类的实例方法时,必须有一个成员内部类实例,成员内部类实例必须寄生在外部类实例里)。


c、当在成员内部类的方法内访问某个变量时,系统优先在该方法内查找是否存在该名字的局部变量;不存在则查找内部类的成员变量,最后查找外部类的成员变量。如果三个地方存在同名变量,可以使用 Outter.this、this、直接变量名来区分。


d、外部类想要访问内部类某个变量时,不可直接访问,必须先创建内部类对象再由内部类对象调用访问。


静态的成员变量和方法可以直接通过类进行访问,而不必创建类的实例,而访问非静态内部类必须实例化才可以,所以没有必要在非静态内部类里面声明静态的成员变量和方法)



局部内部类:


定义在方法里的类称为局部内部类。由于局部内部类不能在定义它方法之外的地方使用,因此,也不能使用访问控制符和 static 修饰。注意,局部内部类访问方法参数或者方法内变量的时候,参数或者变量会默认使用 final 修饰。



java外部类定义 java内部类和外部类的区别_匿名内部类_02




静态内部类:


a、使用 static 修饰的内部类称为静态内部类。此时内部类属于外部类本身而不属于外部类的某个对象。


b、静态内部类可以包含静态成员和非静态成员。根据静态成员不能访问非静态成员的规则,静态内部类不能访问外部类的非静态成员,只能访问外部类的类成员。或者先实例化外部类对象,再由此对象调用外部类非静态成员。



java外部类定义 java内部类和外部类的区别_匿名内部类_03




匿名内部类:


a、匿名内部类在 Android 中使用的比较多,基本都是接口监听方面。匿名内部类适合创建那种只需一次使用的类,不能重复使用。


b、匿名内部类必须继承一个父类,或实现一个接口,但也只能继承一个类或实现一个接口。


c、匿名内部类不能是抽象类,因为创建匿名内部类的时候会立即创建匿名内部类的对象。


d、匿名内部类没有构造器。但是可以定义初始模块化代码。


e、通过实现接口创建匿名内部类时,匿名内部类只有一个隐式的无参构造器。如下:



java外部类定义 java内部类和外部类的区别_外部类_04



f、如果通过继承父类来创建匿名内部类时,匿名内部类隐式拥有和父类相似的构造器,此处的相似指的是拥有相同的形参列表,如下:



java外部类定义 java内部类和外部类的区别_匿名内部类_05



g、创建匿名内部类时,必须实现接口或者抽象父类中所有抽象方法。也可以重写父类中的普通方法。在 Java8 之前,局部内部类,匿名内部类访问的局部变量必须使用 final 修饰;Java8 开始取消了这个限制。如果匿名内部类访问局部变量,该局部变量相当于自动使用 final 修饰。



java外部类定义 java内部类和外部类的区别_java外部类定义_06