内部类
内部类:指在一个外部类内部在定义一个类.内部类作为一个外部类的成员.并依附外部类而存在.
分为4种 源码传送门
- 成员内部类 作为外部类的一个成员存在,与外部类的属性方法并列.
-
1 public class Outer { 2 private static int i = 1; 3 private int j = 10; 4 private int k = 20; 5 6 public static void outer_f1(){ 7 8 } 9 public void outer_f2(){ 10 11 } 12 13 //成员内部类中不能定义静态成员 14 //成员内部类中,可以访问所有外部成员 15 class Inner{ 16 // static int inner_i = 100;//内部类不允许定义静态变量 17 int j = 100;//内部类和外部类实例变量可以共存 18 int inner_i = 1; 19 void inner_f1(){ 20 System.out.println(i); 21 22 //内部类访问内部类自己变量名时,直接用变量名 23 System.out.println(j); 24 //也可以this.变量名 25 System.out.println(this.j); 26 27 //在内部类中访问外部类中与内部类同名的实例变量 用外部类名.this.变量名 28 System.out.println(Outer.this.j); 29 //没有与外部类同名的变量,内部类可以直接访问外部类变量 30 System.out.println(k); 31 outer_f1(); 32 outer_f2(); 33 } 34 } 35 36 public void outer_f3(){ 37 //外部方法使用内部方法需要创建内部类对象 38 Inner inter = new Inner();//对象实例化 39 inter.inner_f1(); 40 } 41 //外部类的静态方法访问成员内部类,与在外部类访问成员内部类一样. 42 public static void outer_f4(){ 43 // step1: 建立外部类对象 44 Outer outer = new Outer(); 45 // step2:根据外部类对象建立内部类对象 46 Inner inner = outer.new Inner(); 47 // setp3:访问内部类方法 48 inner.inner_f1(); 49 } 50 //主方法main 51 public static void main(String[] args) { 52 // outer_f4();//和下面3条输出结果一样 53 54 // Outer outer = new Outer(); 55 // Inner inner = outer.new Inner(); 56 // inner.inner_f1(); 57 58 Outer outer = new Outer(); 59 Outer.Inner outin = outer.new Inner(); 60 outin.inner_f1(); 61 } 62 }
注意:内部类是一个编译时的概念,一旦编译成功,就会成为不完全不同的2个类.对于一个名为Outer的外部类和其内部Inner的内部类.编译完成后出现Outer.class和Outer$Inner.class.
局部内部类 定义在外部内类的方法内部. -
-
1 public class Outer { 2 private int s = 100; 3 private int out_i = 10; 4 5 public void f(final int k){ 6 final int s = 200; 7 int i = 1; 8 final int j = 10; 9 10 //局部内部类,定义在方法内部 11 class Inner{ 12 int s = 300; //可以定义与外部内同名变量 13 int inner_i = 100; 14 //static int m =20;//不能定义静态变量 15 Inner (int k){ 16 inner_f(k); 17 } 18 void inner_f(int k) { 19 //如果内部类没有与外部类同名变量,内部类可以直接访问外部类实例变量 20 System.out.println(out_i); 21 //可以访问外部类方法内的局部变量,但是变量必须是final 22 System.out.println(j); 23 //如果内部和外部均有,访问的是内部类变量. 24 System.out.println(s); 25 //用this.变量名访问的是内部变量 26 System.out.println(this.s); 27 //访问外部变量用外部类名.this.s 28 System.out.println(Outer.this.s); 29 } 30 } 31 new Inner(k); 32 } 33 34 //主方法main 35 public static void main(String[] args) { 36 //访问内部内必须先有外部类对象 37 Outer out = new Outer(); 38 out.f(3); 39 } 40 }
- 静态内部类(嵌套类)
- 不需要内部类与外部类之间有联系,内部类可以声明为static.不同内部类隐含保存了一个引用,指向创建他的外围类对象
- 当内部类使用static 时,
- 要创建一个嵌套类对象就不需要其外围类对象.
- 不能从嵌套类对象中访问非静态类的外围类对象
-
1 public class Outer { 2 private static int i= 1;//定义静态变量 3 private int j = 10; 4 public static void outer_f1(){ 5 6 } 7 public void outer_f2(){ 8 9 } 10 //静态内部类 11 //静态内部类中可以用public ,protected private 修饰 12 //可以定义静态成员和非静态成员 13 static class Inner{ 14 static int inner_i = 100; 15 int inner_j = 200; 16 static void inner_f1(){ 17 System.out.println("Outer.i:"+i); 18 outer_f1(); 19 } 20 void inner_f2(){ 21 // 静态内部类不能访问外部类的非静态成员(包括变量和方法) 22 // System.out.println("Outer.i"+j); 23 // outer_f2(); 24 } 25 } 26 27 public void outer_f3(){ 28 //外部类访问内部类的静态成员 内部类.成员变量 29 System.out.println(Inner.inner_i); 30 Inner.inner_f1(); 31 32 //外部类访问内部类非静态成员 实例化内部类即可 33 Inner inner = new Inner(); 34 inner.inner_f2(); 35 } 36 public static void main(String [] args ){ 37 new Outer().outer_f3(); 38 } 39 }
- 匿名内部类 简而言之就是没有名字的内部类
- 满足以下条件使用内部类比较合适
- 只用到类的一个实例.
- 类在定义后马上用到.
- 类非常小(SUN推荐4行代码以下).
- 给类命名并不会导致你的代码更容易被理解.
- 使用匿名内部类注意以下几个原则
- 匿名内部类不能有构造方法.
- 不能定义任何静态成员, 方法,和类.
- 匿名内部类不能是public,protected,private,static.
- 只能创建匿名内部类的一个实例.
- 一个匿名内部类一定是在new的后面.用其隐含实现一个接口或者实现一个类.
- 因为匿名内部类是一个局部内部类,所有局部内部类的限制对其均有效.
- 代码 参考http://www.cnblogs.com/nerxious/archive/2013/01/25/2876489.html
- 满足以下条件使用内部类比较合适