1. 非静态内部类
1.1 非静态内部类可以看成是外部类的一个非静态成员,可以加之普通成员的限制,修饰符,不能在静态上下文中使用。
1.2 在外部类中创建内部类对象的语法与普通的创建对象的语法相同,使用new操作符调用相应构造器即可。
1.3 在外部类外创建内部类对象的基本语法如下:
<外部类类名>.<内部类类名> 引用变量=<外部类对象引用>.new <内部类构造器>
<外部类类名>.<内部类类名> 引用变量= new <外部类构造器>.new <内部类构造器>
1.4 内部类可以使用外部类中的任何成员,包括private成员;
1.5 如果在外部类中要访问内部类的非静态成员(内部类不可以有静态成员),需要首先创建内部类的对象,即使是内部类的私有成员,外部类一样可以进行访问。
public class Outter {
private int x =100;
class Inner{
private void show(){
System.out.println("成功调用内部类的私有方法!");
System.out.println("在内部类中调用了外部类的私有变量x,并显示x的值为:"+ x);
}
}
public void getInnerShow(){
Inner i = new Inner();
i.show();
}
public static void main(String[] args){
Outter o = new Outter();
o.getInnerShow();
}
}
1.6 非静态内部类不可以有静态成员。
1.7 预定义对象引用this是指向当前对象自身的引用,其作用之一是可以区别同名的成员变量和局部变量。但当内部类对象与外部类对象有同名的成员变量时,只是使用this就无法从内部类中访问外部类的同名成员变量,因为此时this指向内部类对象自身。如果在内部类中需要使用外部类对象的this,则使用如下语法:
<外部类名>.this.<外部类中需要被访问的成员名>
class Outter{
int x =100;
class Inner{
int x=20;
public void show(){
System.out.println("访问外部类Outter中的成员变量x="+Outter.this.x);
System.out.println("访问内部类Inner中的成员变量x="+this.x);
}
}
}
public class Sample15_5 {
public static void main(String[] args){
Outter o =new Outter();
Outter.Inner i = o.new Inner();
i.show();
}
}
2. 局部内部类
2.1 局部内部类扮演局部角色,其作用域与局部变量相同,只在其所在的语句块中有效。
2.2 在局部内部类中一样可以访问外部类的成员,但却不可以访问同在一个局部的普通局部变量,可以访问final的局部变量。
2.3 如果局部内部类位于静态方法中,则只能访问外部类静态的成员。
3. 静态内部类
3.1 在外部类之外创建静态内部类对象的基本语法:
<外部类类名>.<内部类类名> 引用变量 = new <外部类类名>.<内部类构造器>
说明:不需要创建外部类对象,直接调用内部类的构造器即可。
3.2 静态内部类也称为静态嵌套类或顶级嵌套类。
3.3 静态/非静态内部类的区别:
非静态内部类应该与外部类的对象存在着对成员的共享关系,其是外部类对象组成的一部分,用来辅助外部类对象工作;
而静态内部类与外部类对象之间则不存在这样的关系,静态内部类其实已经脱离了外部类的控制,在创建其对象时已经不需要外部类对象的存在,其实质只是一个放置在别的类中的普通类而已,static关键字只是说明其在创建对象时不依赖于外部类对象的存在,并不是说这个类本身是静态的。
4. 匿名内部类
4.1 匿名内部类要么实现一个接口,要么继承一个类,不能既实现接口又继承一个类。基本语法如下:
new <匿名内部类要继承父类的对应构造器>() {类体}
或
new <接口名> () {类体}
4.2 匿名内部类类体中可以重写父类的方法,或提供自己新的方法与成员。但新的方法或成语只能自己内部使用,外部无法使用(因为无法声明匿名内部类类型的引用)。
4.3 匿名内部类只能创建一次对象,而且只能通过多态来进行使用(用父类引用或接口类型引用指向该对象)。
5. 内部接口
5.1 定义在类中的内部接口无论是否有static修饰,扮演的都是静态成员的角色,不能扮演局部变量的角色。
5.2 定义在接口中的内部接口其实是将普通接口放到了一个接口内部,在使用上没有很大的不同,实现内部接口与普通接口的具体方法完全一样。
外部接口外实现内部接口的基本语法如下:
class <类名> implements <外部接口名>.<内部接口名>
{
//类体,包括实现内部接口的代码
}