可以将一个类的定义放在另一个类的定义内部,这就是内部类。而包含内部类的类被称为外部类。
主要作用
内部类提供了更好的封装,可以把内部类隐藏在外部类之内,不允许同一个包中的其他类访问该类。
内部类的方法可以直接访问外部类的所有数据,包括私有的数据。
内部类所实现的功能使用外部类同样可以实现,只是有时使用内部类更方便。
内部类允许继承多个非接口类型。
内部类的类体中不可以声明类变量和类方法。
注:内部类是一个编译时的概念,一旦编译成功,就会成为完全不同的两类。对于一个名为outer的外部类和其内部定义的名为inner的内部类。编译完成后出现outer.class和outer$inner.class两类。所以内部类的成员变量/方法名可以和外部类的相同。
详细分类
成员内部类
相当于所在外部类的一个成员变量,可以使用任意访问修饰符。内部类里可以直接访问外部类的方法和属性。如果外部类和内部类具有相同的成员变量或方法,内部类默认访问自己的成员变量或方法,如果要访问外部类的成员变量,可以使用 this 关键字。定义成员内部类后,必须使用外部类对象来创建内部类对象,即:
内部类 对象名 = 外部类对象.new 内部类();
所以成员内部类不能含有static的变量和方法,因为成员内部类需要先创建了外部类,才能创建它自己的。
2. 静态内部类
静态内部类是 static 修饰的内部类,通常被称为嵌套类。不能直接访问外部类的非静态成员,但可以通过 new 外部类().成员 的方式访问。如果外部类的静态成员与内部类的成员名称相同,可通过类名.静态成员访问外部类的静态成员;如果外部类的静态成员与内部类的成员名称不相同,则可通过成员名直接调用外部类的静态成员。嵌套类和普通的内部类还有一个区别:普通内部类不能有static数据和static属性,也不能包含嵌套类,但嵌套类可以。而嵌套类不能声明为private,一般声明为public,方便调用。创建静态内部类的对象时,不需要外部类的对象,可以直接创建:
内部类 对象名 = new 内部类();
局部内部类
局部内部类,是指内部类定义在方法和作用域内。局部内部类也像别的类一样进行编译,但只是作用域不同而已。不能使用public或private访问说明符进行声明。局部类的方法只能引用定义为final的局部变量。
匿名内部类
当使用类创建对象时,程序允许把类体与对象的创建组合在一起。也就是说。类创建对象时,除了构造方法还有类体,此类体被认为是该类的一个子类去掉类声明后的类体,称为匿名类。匿名类就是一个子类,由于无名可用,不能用来声明对象,但是却可以直接用匿名类创建对象。
使用匿名类时,必然是在某个类中直接用匿名类创建对象,因此匿名类一定是内部类。因为没有名字,不能重用,通常用来简化代码。使用匿名内部类还有个前提条件:必须继承一个父类或实现一个接口。匿名内部类是不能加访问修饰符的。当所在的方法的形参需要在内部类里面使用时,该形参必须为final。要注意的是,new 匿名类,这个类是要先定义的。
尽管匿名类创建的对象没有经过类声明步骤,但匿名类对象的引用必须传递给一个匹配的参数,匿名类的主要用途就是向方法的参数传值。
//假设f(B x)是一个方法
void f(B x) {
//x调用B中的方法
}
//其中参数是B类对象,那么在调用方法f时可以向其参数x传递一个匿名对象,如
f (new B() {
//匿名类的类体
}
);
此外还有一种和接口相关的匿名类。类似的,Java 允许直接用接口名和一个类体创建一个匿名对象。如果某个方法的参数是接口类型,那么可以使用接口名和类体组合创建一个匿名对象传递给方法的参数,类体必须要实现接口中的全部方法。
本文详细介绍了Java内部类的概念及分类,包括成员内部类、静态内部类、局部内部类和匿名内部类。解释了它们各自的特性和使用场景,并强调了内部类如何提供更好的封装性。
1256

被折叠的 条评论
为什么被折叠?



