Java核心类库:内部类那点事儿-1

上一篇 / 下一篇  2012-04-18 14:35:51 / 个人分类:Java

内部类:定义在类的内部的类51Testing软件测试网4Jb k2qn:GK9],L

  为什么需要内部类?51Testing软件测试网9Y3Yb Fm;Q bx,z3?.f)I

)wYd dR0  ● 典型的情况是,内部类继承自某个类或实现某个接口,内部类的代码操作创建其的外围类的对象。所以你可以认为内部类提供了某种进入其外围类的窗口。51Testing软件测试网6q,u-Jiy

,Ay0v4Tc H8?6k0  ●java中的内部类和接口加在一起,可以实现多继承。

9D!q b[G1Rj OQ,h051Testing软件测试网Gd-`@D9o E-\Kw

  ● 可以使某些编码根简洁。

xM&_h0t%t(l\$~051Testing软件测试网!S \^6HF;g

  ● 隐藏你不想让别人知道的操作。51Testing软件测试网#ls*mt5@+d*xJ0S

V#{,z$J5~&N0  使用内部类最吸引人的原因是:

[X k rW.x] qE S051Testing软件测试网;]B&X-qKG8r*]!{ Y,r

  每个内部类都能独立地继承自一个(接口的)实现,所以无论外围类是否已经继承了某个(接口的)实现,对于内部类都没有影响。如果没有内部类提供的可以继承多个具体的或抽象的类的能力,一些设计与编程问题就很难解决。从这个角度看,内部类使得多重继承的解决方案变得完整。接口解决了部分问题,而内部类有效地实现了“多重继承”。51Testing软件测试网 tBh4h^\

"S,L7`~a"_4jk^ i&R0  内部类分为: 成员内部类、静态嵌套类、方法内部类、匿名内部类。51Testing软件测试网 o4[eRY \`

%w6oGWWFC0  特点:

Qsj5f}051Testing软件测试网 [T \2r5[&]/]

  一、内部类仍然是一个独立的类,在编译之后内部类会被编译成独立的.class文件,但是前面冠以外部类的类命和$符号。51Testing软件测试网]{-t@U2t

/`f:HM(W0  二、内部类可以直接或利用引用访问外部类的属性和方法,包括私有属性和方法(但静态内部类不能访问外部类的非静态成员变量和方法)。内部类所访问的外部属性的值由构造时的外部类对象决定。51Testing软件测试网ACsT^#N)]wY

51Testing软件测试网3lb*nC8X!T2W

  三、而外部类要访问内部类的成员,则只能通过引用的方式进行,可问内部类所有成员

3~d,u8Yu)T051Testing软件测试网/B1DJ;A{m S-i

  四、访问机制:

-P!F`8|\7b!n*d&b"|0

,Q(ij-t+a-p0

th7e$DZi0
  1. System.out.println(this.x);或System.out.println(x);//内部类访问内部类的成员变量或成员方法可用此方法。 
  2. System.out.println(OuterClass.this.x);//内部类访问外部类的同名变量时可用此方法,如果没有同名可用System.out.println(x);

@ K'f1o0eVDM!\051Testing软件测试网!m e9to hIk8v

51Testing软件测试网d l+wo"~8e(d

  五、内部类可以使用任意的范围限定:public/private/protected class InnerClass,且严格按照这几种访问权限来控制内部类能使用的范围。普通类的范围限定只可以是public或者不加。

W3RG9|M,jX0

Dd[-R3K P0  六、内部类的命名不允许与外部类 重名,内部类可以继承同级的内部类,也可继承其它类(除内部类和外部类)。

C uG~DJ"[,? Un\051Testing软件测试网$k gS{}#qT!E

  七、内部类可以定义为接口,并且可以定义另外一个类来实现它

TY|G2aTS*Is0

s#r4T(Yh0  八、内部类可以定义为抽象类,可以定义另外一个内部类继承它

7cfB z\)p051Testing软件测试网O7BD ]RK;u^

  九、内部类使用static修饰,自动升级为顶级类,外部类不可以用static修饰,用OuterClass.InnerClass inner=new OuterClass.InnerClass();创建实例。内部类还可定义为final.

WtW*m j0

}3v |PRa/n'_l4p0  十、内部类可以再定义内部类(基本不用)

"g{)[TX051Testing软件测试网g8{rK.Z+S'Tam

  十一、方法内的内部类:51Testing软件测试网~1q~d/\)L]

51Testing软件测试网SJ8L2r5}z O#i

  方法内的内部类不能加范围限定(protected public private)

V%h8?tH:F0

k B-[8J*V P0  方法内的内部类不能加static修饰符

?r"]xj ]$T Y0

p,_f$ZO jlJ'R0  方法内的内部类只能在方法内构建其实例

&[_I*L Q051Testing软件测试网s-uu*G&G^i*E

  方法内的内部类如果访问方法局部变量,则此局部变量必须使用final修饰51Testing软件测试网wN$`b9F{

51Testing软件测试网*_[fEEV

  1)静态内部类(静态嵌套类)51Testing软件测试网K c!Z&H1b|B i

4mL Eg {8Q0  从技术上讲,静态嵌套类不属于内部类。因为内部类与外部类共享一种特殊关系,更确切地说是对实例的共享关系。而静态嵌套类则没有上述关系。它只是位置在另一个类的内部,因此也被称为顶级嵌套类。

O)n _*|cD`3m0

4r1v| Q,@sd W(Y)c0  静态的含义是该内部类可以像其他静态成员一样,没有外部类对象时,也能够访问它。静态嵌套类不能访问外部类的成员和方法。51Testing软件测试网LDDf1Z0gr1h

51Testing软件测试网 B ~%~k NV)J%|LE8H

语法

T5i3F$H V_ N9F2y+Q051Testing软件测试网4{ wh ?x C8br

| LCr(N \l0

4s o6R:HKV6jN#S0

  1. package com.tarena.day13;  
  2. import com.tarena.day13.Foo.Koo;  
  3. /** 
  4.  * 静态类内部语法演示 
  5.  */ 
  6. public class StaticInner {  
  7.  public static void main(String[] args) {  
  8.   Koo koo = new Koo();  
  9.   System.out.println(koo.add());//4 
  10.  }  
  11. }  
  12. class Foo{  
  13.  int a = 1;  
  14.  static int b = 3;  
  15.  /** 静态内部类,作用域类似于静态变量,属于类的 */ 
  16.  static class Koo{  
  17.   public int add(){  
  18.    //a ,不能访问a 
  19.    return b+1;  
  20.   }  
  21.  }  
  22. }

1hSsFK i.y2a(E051Testing软件测试网ha0dJ!?.o

51Testing软件测试网wQ-Ff~

sFU&{ R7O&N9l8Oig0  2)成员内部类51Testing软件测试网XL1XF/eu'bp\

O!lF-FK} _ Z0  * 1 成员内部类必须利用外部类实例创建

V-Gl4CW:kV051Testing软件测试网 A3DN!P&zE i,g

  * 2 成员内部类可以共享外部类的实例变量

dS'a(^t"~r0

g9Ls*J`NuPy%c6Z'm v0

'tP2lA6Fb,~^8}.Oe0

SE~ w#o5\(S'Py-x!W0

  1. import com.tarena.day13.inn.Goo.Moo;  
  2. public class InnerClassDemo {  
  3.  public static void main(String[] args) {  
  4.   //Moo moo = new Moo(); //编译错误,必须创建Goo的实例 
  5.   Goo goo = new Goo();  
  6.   Moo moo = goo.new Moo();//利用goo实例创建Moo实例 
  7.   Moo moo1 = goo.new Moo();  
  8.   //moo和moo1共享同一个goo实例的实例变量 
  9.   System.out.println(moo.add());//2 
  10.   System.out.println(moo1.add());//2 
  11.   Goo goo1 = new Goo();  
  12.   goo1.a = 8;  
  13.   Moo m1 = goo1.new Moo();  
  14.   Moo m2 = goo1.new Moo();  
  15.   System.out.println(m1.add());//9 
  16.   System.out.println(m2.add());//9 
  17.     
  18.  }  
  19. }  
  20. class Goo{  
  21.  int a = 1;  
  22.  /**成员内部类*/ 
  23.  class Moo{  
  24.   public int add(){  
  25.    return a+1;  
  26.   }  
  27.  }  
  28. }
51Testing软件测试网0MH;F Xbq7]O

51Testing软件测试网O\;M*np

51Testing软件测试网&^|8A-h LN

o;F@6[%\0  3)局部内部类(方法内部类)

v,r}O Ke#m-hW051Testing软件测试网!{F#`Y-E1SJZA

  (1)方法内部类只能在定义该内部类的方法内实例化,不可以在此方法外对其实例化。

*e![*q"OB9^051Testing软件测试网t_2Hhhg2M O

  (2)方法内部类对象不能使用该内部类所在方法的非final局部变量。

^SZ`7FaY)J]#[0

tp6vs@0  因为方法的局部变量位于栈上,只存在于该方法的生命期内。当一个方法结束,其栈结构被删除,局部变量成为历史。但是该方法结束之后,在方法内创建的内部类对象可能仍然存在于堆中!例如,如果对它的引用被传递到其他某些代码,并存储在一个成员变量内。正因为不能保证局部变量的存活期和方法内部类对象的一样长,所以内部类对象不能使用它们。用法51Testing软件测试网.bNl BR~

C6Iz@H t0

8g6qM*zz5X0

2P(b9e4n5Hq1U0

  1. package com.tarena.day13.inn;  
  2. import java.util.Comparator;  
  3. /** 
  4.  * 局部内部类 
  5.  */ 
  6. public class LocalInnerClassDemo {  
  7.  public static void main(String[] args) {  
  8.   int a = 5;  
  9.   final int b = 5;  
  10.   //局部内部类,定义在方法内部,作用域类似于局部变量 
  11.   //仅仅在方法内部可见 
  12.   //在局部内部类中可以访问方法中的局部final变量 
  13.   class Foo{  
  14.    public int add(){  
  15.     return  b;//正确 
  16.     //return a;//编译错误 
  17.    }  
  18.   }  
  19.     
  20.   Foo foo = new Foo();  
  21.   //临时的自定义比较规则 
  22.   class ByLength implements Comparator<String>{  
  23.    public int compare(String o1,String o2){  
  24.     return o1.length()-o2.length();  
  25.    }  
  26.   }  
  27.  }  
  28. }
51Testing软件测试网W9T(Xoz K6dZ`7a


TAG:

 

评分:0

我来说两句

Open Toolbar