内部类:定义在类结构中的另一个类
类中定义的成员
字段
方法
内部类
为什么使用内部类
(1)增强封装,把内部类隐藏在外部类之内,不许其他类访问该类
(2)内部类能提高代码的可读性和可维护性,把小型类嵌入到外部类中接构上代码更靠近
(3)内部类可以直接访问外部类的成员
内部类根据不同的修饰符或者定位的位置不同分成四张表
四种内部类
(1)实例内部类:内部类没有使用static修饰
(2)静态内部类:内部类使用了static修饰
(3)局部内部类:在方法中定义的内部类
(4)匿名内部类适合于仅一次使用的类,属于局部内部类的特殊情况
实例内部类 | 静态内部类 | 局部内部类 | |
主要特征 | 内部类的实例引用特定的外部类的实例 | 内部类的实例与外部没有任何关联 | 可见范围是所在的方法 |
可用修饰符 | 访问控制修饰符 abstract final | 访问控制修饰符 static abstract final | abstract final |
可以访问外部类的那些成员 | 可以直接访问外部类的所有成员 | 只能访问外部类的静态成员 | 可以直接访问外部类的所有成员,并且能访问所在方法的final类型的变量和参数 |
拥有成员类型 | 只能拥有实例成员 | 可以拥有静态成员和实例成员 | 只能拥有实例成员 |
外部类如何访问内部类 | 必须通过内部类的实例访问 | 对于静态成员,可以通过内部类完整的类名访问 | 必须通过内部类的实例访问 |
内部类可以看做外部类的的一个成员,类似于字段,那么可以缺省/public/private/protected修饰,还可以使用static修饰
对于内部类
实例内部类:没有使用static修饰的内部类,说明内部类属于外部类的对象
特点
(1)创建实例内部类前,必须存在外部类对象,通过外部类对象创建内部对象(当存在内部类对象时,一定存在外部类对象)
(2)实例内部类的实例自动持有外部类的引用,内部类可以直接访问外部类成员
(3)外部类中不能直接访问内部类的成员,必须通过内部类的实例去访问
(4)实例内部类中不能定义静态成员,只能定义实例成员
(5)如果实例内部类和外部类存在同名字段或者方法abc,那么在内部类中
this.abc :表示访问内部类
外部类.this.abc:表示访问外部类成员
package HelloWorld;
class Outter{
String name="Outter.name";
public void ooxx() {
System.out.println(this.new Inner().name); //Inner.name
}
class Inner{
int age=17;
String name ="Inner.name";
public void test() {
String name="locat.name";
System.out.println(name); //locat.name
System.out.println(this.name); //Inner.name
System.out.println(Outter.this.name);//Outter.name
}
}
}
public class InstanceInnerClassDome {
public static void main(String[] args) {
Outter out =new Outter();
out.ooxx();
Outter.Inner inn=out.new Inner();
inn.test();
}
}
静态内部类
使用static修饰的内部类
特点
(1)静态内部类的实例不会自动持有外部类的特定实例的引用,在创建内部类实例时,不必创建外部类的实例
(2)静态内部类可以直接访问外部类的静态成员,如果访问外部类的实例成员,必须通过外部类的实例去访问
(3)在静态内部类中可以定义静态成员和实例成员
(4)测试类可以通过完整的的类名去访问静态内部类的静态成员
package HelloWorld;
class Outter{
String name="Outter.name";
static String name2="static.name2";
public void ooxx() {
System.out.println(name2);
}
static class Inner{
static int age=17;
String name ="Inner.name";
public void test() {
String name="locat.name";
System.out.println(name);
System.out.println(name2);
System.out.println(this.name);
System.out.println(Outter.Inner.age);
}
}
}
public class InstanceInnerClassDome {
public static void main(String[] args) {
System.out.println(Outter.Inner.age);
}
}
局部内部类(不使用):
在方法中定义的内部类,其可范围是当前变量和局部变量是同一个等级
(1)局部内部类只能在当前方法中使用
(2)不能使用 public private static protected修饰
(3)局部内部类和实例内部类一样不能包含静态变量
(4)局部内部类和实例内部类,可以访问外部类的所有成员
(5)局部内部类访问的局部变量必须使用final修饰(在Java8中是隐式加上final 依然是常量,不能修改)
匿名内部类是只使用一次的类
(1)匿名内部类本身没有构造器,但会调用父类构造器
(2)匿名类尽管没有构造器,但是可以再在匿名类中初始化代码块,JVM调用父构造器,会执行该段代码
(3)内部类处理可以继承之外,还可以实现接口
new 父类构造器(实参列表)或者接口{
//匿名代码块实例
}
注意:匿名内部类必须继承一个父类或者实现一个接口,最多只能有一个实现或者继承