一、静态嵌套类
1.静态嵌套类用static修饰符修饰。格式:
class OuterClass{
//成员变量和方法
static class InnerClass{
//成员变量和方法
}
}
2.静态嵌套类与静态方法类似,只能访问外层类的static成员,不能访问外层类的实例变量和实例方法,只有通过对象引用才能访问。
3.静态嵌套类不存在对外部类的引用,不通过外部类的实例就可以创建一个对象。
4.static嵌套类中的方法不能通过this关键字访问外层类的实例成员。
5.类的内部还可以定义接口,其属性默认为static,但也可以指定为任何的访问修饰符。
6.内部类中还可以有内部类,多层嵌套。
7.程序实例:
public class OuterInterface {
String s1="Hello";
static String s2="World";
int i=0;
interface InnerInterface{
void show();
}
static class InnerClass implements InnerInterface{
public void show() {
System.out.println("s1="+new OuterInterface().s1);
System.out.println("s2="+s2);
}
}
public static void main(String[] args) {
InnerClass inner=new InnerClass();
inner.show();
OuterInterface.InnerClass inner2=new OuterInterface.InnerClass();
inner2.show();
}
}
解释:
输出:
s1=Hello
s2=World
s1=Hello
s2=World
(1)OuterInterface类的内部定义了一个接口InnerInterface和一个类InnerClass。且InnerClass类实现了InnerInterface接口。
(2)在main方法中用两种格式生成了InnerClass类的两个对象。但是要注意:如果要在除外部类的非静态方法之外的任何位置创建内部类的对象,则必须将该对象的类型指定为OuterClassName.InnerClassName,即上面代码的第二种创建方法。
(3)s1不是static的,s2是static的,所以内部类可以直接使用s2,但不能直接使用s1,而是需要外层类对象的引用。
二、成员内部类
1.成员内部类不用static修饰,定义在外层类的类体中。
2.成员内部类的访问修饰符可以是private、public、protected或默认。
3.成员内部类中可以有自己的成员变量和方法,以及构造器。
4.成员内部类可以视为外层类的一个成员,因此可以自由访问外部类所有成员,包括私有成员。
5.关于创建成员内部类的对象:
假如有一外层类TopLevel和一成员内部类Inner,进行成员内部类对象的创建:
TopLevel topLevel = new TopLevel();
TopLevel.Inner inner=topLevel.new Inner();
或者这样创建:
TopLevel.Inner inner=new TopLevel().new Inner();
6.注意:
(1)成员内部类中不能有static修饰的成员
(2)成员内部类可以使用abstract和final修饰
三、局部内部类
1.局部内部类是在外层类的方法体或者语句块内部定义的类。
2.局部内部类不可作为外部类的成员,只对局部块有效。类比局部变量。
3.在定义局部内部类的块之外是无法访问这个内部类的,所以不能有任何访问修饰符。
4.注意:
(1)局部内部类可以有abstract、final修饰。
(2)局部内部类可以访问外层类的成员,要访问其所在方法的参数和局部变量时,这些参数和局部变量必须用final修饰。
(3)static方法中的局部内部类可以访问外层类定义的static成员,实例成员不可以。
5.程序实例:
public class MyOuter {
private int size=5;
public Object makeInner(int localVar) {
final int FinalLocalVar=localVar;
class MyInner{//局部内部类
public String toString() {
return "Size:"+size+" LocalVar:"+FinalLocalVar;
}
}
return new MyInner();
}
public static void main(String[] args) {
Object obj=new MyOuter().makeInner(47);
System.out.println(obj.toString());
}
}
解释:
输出:
Size:5 LocalVar:47
(1)由于不能直接访问局部内部类,所以先创建了一个MyOuter类的对象,然后调用其makeInner方法,返回一个MyInner类的对象obj。
(2)toString方法要调用makeInner方法的成员FinalLocalVar,所以其被final修饰。
(3)MyInner类可以外层类的成员size。
四、匿名内部类
1.可以将类的定义与实例的创建在一起完成(在定义类的同时创建一个实例),这种方式定义的没有名字的类成为匿名内部类。
2.格式:
new ClassOrInterfaceName(){//ClassOrInterfaceName是继承的类的名字或实现的接口的名字
//类体
}
2.匿名内部类可以继承一个类,或者实现一个接口,但不能同时做到。不需要extends和implements关键字。
3.类体中不能有构造方法,也不能用new关键字创建对象实例。
3.上面的格式声明可以视为一个表达式,进行赋值或直接使用。
例如:
(1)TypeName obj=new Name() {
//类体
};
(2)someMethod(new Name() {
//类体
});
4.程序实例:
interface Printable{
void print(String message);
}
public class AnonymousDemo {
public static void main(String[] args) {
Printable printer=new Printable() {
public void print(String message) {
System.out.println(message);
}
};//匿名内部类
printer.print("Anonymous Class");
}
}
解释:
输出:
Anonymous Class
这里用匿名内部类实现了一个接口并创建了一个对象printer,之后调用其方法输出了Anonymous Class。
参考资料:
《java语言程序设计》——清华大学出版社