首页 > 代码库 > 关于Java内部类的一些知识

关于Java内部类的一些知识

 

成员内部类: 
相当于类的非静态成员,可以用权限修饰符来修饰,包括private、protected、public. 
1、定义成员内部类 
class Outter { 
//非静态内部类 
class Inner { 
//内部类成员 
int i = 12; 

//外部类的普通成员 
int j = 0; 

2、外部类之内创建成员内部类对象 
语法和普通的创建对象相同,用new操作符调用相应的构造方法即可。注意的是,非静态内部类属于外部类的非静态成员,不能在静态上下文使用。 
例子: 
class Outter { 
//非静态内部类 
class Inner { 
//内部类成员 
int i = 12; 
public void innerTest() { 
System.out.println(“Inner Class Method”); 


//外部类的普通成员 
int j = 0; 
public void test() { 
Inner inner = new Inner(); 
inner.innerTest(); 


3、外部类之外创建成员内部类对象 
既然是外部类的非静态成员,就必须在外部类对象存在的情况下使用。 
基本语法是 
<外部类类名>.<内部类类名> 引用变量名称 = <外部类对象的引用>.new <内部类构造器>; 
<外部类类名>.<内部类类名> 引用变量名称 = new <外部类构造器>.new <内部类构造器>; 
(1)、创建内部类对象时对象引用必须是<外部类类名>.<内部类类名> 
(2)、调用内部类的构造方法不能直接用new 而是要用<外部类对象的引用>.new调用 
例子: 
class Outter { 
//非静态内部类 
class Inner { 
//内部类成员 
int i = 12; 
public void innerTest() { 
System.out.println(“Inner Class Method”); 


//外部类的普通成员 
int j = 0; 

class MainTest { 
public static void main(String[] args) { 
Outter outter = new Outter(); 
Outter.Inner inner = outter.new Inner(); 
inner.innerTest(); 


在外部类之外访问内部类时需要注意权限修饰符的限制,这点和类成员一样。 
3、内部类编译后生成的.class文件名称格式是<外部类类名>$<内部类类名>。 

4、内部类与外部类之间的成员互相访问 
内部类可以访问外部类的任何成员,包括private成员。 
外部类访问内部类的成员需要创建内部类的对象,之后可以访问内部类的任何成员,包括private成员,需要注意的是成员内部类不可以有静态成员。 
当外部类的成员和内部类的成员重名时单单用this是区分不了的。在内部类中访问外部类的成员时可以用如下语法区分 
<外部类类名>.this.<外部类中需要被访问的成员名>; 

局部内部类 
内部类定义在方法中成为局部内部类,只在局部有效。该类只为所在的方法块服务。 
局部内部类和成员内部类一样可以访问外围类的所有成员,但是不可以访问同在一个局部块的普通局部变量。如果要访问,此局部变量要被声明称final的。 
代码块结束后普通的局部变量会消亡,而创建的局部内部类对象并不会随着语句块的结束而消亡。final的局部变量的存储方式和普通的局部变量不同,其不会因为语句块的结束而消失,还会长期存在,因此可以被局部内部类访问。 
例子: 
public class InnerClassTest1 { 
public static void main(String[] args) { 
Outter outter = new Outter(); 
ForInner forInner = outter.getInner(); 
forInner.sayHello(); 



class Outter { 
ForInner forInner; 
public ForInner getInner() { 
class Inner implements ForInner { 
public void sayHello() { 
System.out.println("你好,我是局部内部类对象,我还存在!"); 


forInner = new Inner(); 
return forInner; 

}

interface ForInner { 
void sayHello(); 

由于局部内部类只在局部有效,所以不能在外面用局部内部类的引用指向局部内部类的对象,只能用局部内部类实现接口并创建局部内部类对象,在外面用接口引用指向局部内部类对象。 
静态方法中的局部内部类只能访问外围类的静态成员,访问不了非静态成员。 
局部内部类生成的.class文件名称是<外部类类名>$<n><内部类类名>其中n是该局部的第几个内部类 

静态内部类 
静态内部类的定义 
class Outter { 
static class Inner { 
/****/ 


由于静态内部类是外部类的静态成员,所以静态内部类只能访问外部类的静态成员。并且创建静态内部类的对象不依赖外部类的对象。在外部类之外创建静态内部类对象的语法如下 
<外部类类名>.<内部类类名> 引用变量名 = new <外部类类名>.<内部类构造器>; 
例子: 
class Outter { 
static class Inner { 
public void sayHello() { 
System.out.println(“成功创建静态内部类对象!”); 


public void getInner() { 
//在外部类中创建静态内部类的对象 
Inner ii = new Inner(); 
ii.sayHello(); 


public class MainTest { 
public static void main(String[] args) { 
//在外部类外创建静态内部类的对象 
Outter.Inner i = new Outter.Inner(); 
i.sayHello(); 
//在外部类中使用静态内部类的对象 
new Outter().getInner(); 


静态内部类实际上已经脱离了外部类的控制,创建对象时也不再需要外部类对象的存在,实质上只是一个放置在别的类中的普通类而已。 

匿名内部类 
基于继承的匿名内部类,语法如下: 
new <匿名内部类要继承父类的对应构造器> { 
//匿名内部类类体 
}; 
基于实现接口的匿名内部类,语法如下: 
new <接口名> { 
//匿名内部类类体,实现接口中的所有方法 

匿名内部类中使用外面的变量要被声明成final的。 
匿名内部类对象初始化的代码可以写在其非静态块中 
匿名内部类生成的.class文件是<外部类类名>$<n>.class n是该类的第几个匿名内部类。 

各种内部类可用的修饰符 
成员内部类 
final、abstract、public、private、protected、static 
静态内部类 
final、abstract、public、private、protected 
局部内部类 
final、abstract 
匿名内部类 
不能对匿名内部类使用修饰符 

内部接口 
定义在类中的内部接口无论是否被static修饰都是静态成员。 
内部接口声明成private的意味着只能被外部类中的某个内部类来实现。 
内部接口不能扮演局部的角色,否则编译报错。因为接口的设计初衷是对外公布,让很多类实现,而局部的角色违背了接口的设计初衷。 
接口中的内部接口属于接口的成员,具有接口成员的所有属性,不能用private进行修饰。 
外部接口外实现内部接口的语法如下: 
class <类名> implements <外部接口名>.<内部接口名> { 
//类体 

关于Java内部类的一些知识