声明:以下内容的理解参考了李刚的《疯狂java讲义》一书,在此致谢作者。
外部类只允许使用的访问范围修饰符只有2个:default、public,
内部类可以使用所有访问范围修饰符和static,由此可见内部类的访问范围比外部类具有更大的灵活性。
(非静态)内部类是外部类的成员,所以在内部类内部可以直接访问外部类成员;而外部类不能直接访问内部类的成员,必须通过创建内部类实例来访问内部类的成员,另外,非静态内部类不能拥有静态成员。
外部类的静态方法禁止创建非静态内部类对象,因为静态成员禁止访问非静态成员。
内部类的创建时机:该类仅在一个外部类中使用。
内部类分为3种:成员内部类(常见);局部内部类(在方法中定义,少见);匿名内部类(少见)。
(非静态)内部类方法中寻找一个变量的顺序:方法中->内部类->外部类
用static修饰内部类,内部类被称为静态内部类,也是属于类的类内部类,此时内部类相当于类的一个静态成员,根据静态成员禁止访问非静态成员原则即可知道内外部类的访问关系了。
静态内部类实例方法禁止直接访问外部类的实例属性,因为静态内部类实例找不到寄生的外部类实例。
java还允许在接口里定义内部类,默认使用public static修饰;也可以定义接口,修饰规则同前者。
在外部类以外的地方定义内部类(包括静态和非静态)变量的语法格式:OutClass.InnerClass varName.
由于非静态内部类的对象必须寄生在外部类对象里,因此在外部类以外的地方创建内部类对象,必须先创建外部类对象,格式是:OuterClassInstance.new InnerClassConstructor();
非静态内部类的子类的构造器必须调用外部类的实例来调用父类的构造器,因为非静态内部类和其子类的对象的创建都必须依附于外部类对象。
当内部类为静态时,使用时可以把外部类名当初内部类的包空间,然后就和一般的类使用方法类似,所以使用内部类时,首选静态内部类。
外部类的子类无法重写内部类,因为内部类的类名已经不是单独的名字,必须加上外部类名称,所以永远无法和子类的内部类名一样。