内部类:
1、一个类放到另一个类的内部来定义,称为内部类
2、包含内部类的类,称为外部类
3、内部类实现了更好的封装,可以把内部类隐藏在外部类内部,不允许其他类访问该类
4、内部类被当成外部类的成员,因此可以直接访问外部类的私有数据,但外部类不可以访问内部类的实现细节,例如内部类的成员变量
5、匿名内部类适合创建仅使用一次的的类
6、内部类比外部类可以多使用单个修饰符:private 、protected、static,外部类不可以使用这三种修饰符
7、非静态内部类不可以定义静态成员
8、定义内部类只需要把类定义在另一个类的任意外置,包括方法内(定义在方法内的内部类称为局部内部类)
9、大部分时候,内部类被作为成员内部类来定义,而不是局部内部类
10、成员内部类是与成员变量、方法、构造器、初始化块相似的类成员
11、局部内部类、匿名类不是类成员
12、成员内部类分两种:静态内部类、非静态内部类
13、内部类作为外部类的成员,可以使用任意访问修饰符
14、外部类的上一级程序单元是包,所以它只有两个作用域:本包内和任何位置,即省略修饰符和 public 修饰符
15、内部类的上一级程序单元是外部类,因此具有四个作用域:同一个类(private),同一个包(省略),父子类(protected),任何位置(public),因此可以使用这四种访问控制权限
16、内部类编译之后的文件命名样式:外部类名$内部类名.class
定义一个内部类,代码示例:
public class Person{ private double weight; public Person(double weight){ this.weight=weight; } private class PersonData{ private String name; private String gender; public PersonData(String name,String gender){ this.name=name; this.gender=gender; } public void info(){ System.out.println("这个人名字是:"+name); System.out.println("这个人性别是:"+gender); //-访问外部类的变量 System.out.println("这个人体重是:"+weight); } } private void test(){ //-获取内部类的实例对象 PersonData pd=new PersonData("张三","男"); //-调用内部类方法 pd.info(); } public static void main(String[] args){ Person p=new Person(75.5); p.test(); } }
编译生成的文件:
运行效果:
17、如果外部类与内部类成员变量同名,或与内部类局部变量同名,通过this. 、外部类名.this.来区分,代码示例:
public class Person{ private String str="外部类成员变量str"; private class PersonData{ private String str="内部类成员变量str"; public void info(){ String str="局部变量str"; //-访问局部变量 System.out.println(str); //-访问内部类成员变量 System.out.println(this.str); //-访问外部类成员变量 System.out.println(Person.this.str); } } private void test(){ PersonData pd=new PersonData(); pd.info(); } public static void main(String[] args){ Person p=new Person(); p.test(); } }
运行结果:
18、外部类不能访问非静态类内部成员,若要访问,需要通过获取非静态内部类实例对象来获取内部类成员,因为创建外部类对象时,非静态内部类、非静态内部类成员可能还不存在,所以获取内部类成员必须先获取内部类实例对象
19、外部类静态方法、静态初始化块不能访问非静态内部类
20、Java不允许在非静态内部类中定义静态成员,但可以包括非静态初始化块,与外部类规则相同