读书人

《Thinking in java》内部类总结

发布时间: 2012-12-28 10:29:05 作者: rapoo

《Thinking in java》——内部类小结

1、在一个类A中定义了一个内部类B之后,如果要在外部类中实例化这个内部类B的话,必须要有类A的引用才能够使用new实例化一个内部类。例子如下所示:

?

public class DotNew {public class Inner{}public static void main(String[] args){DotNew dotNew = new DotNew();Inner inner = dotNew.new Inner();}}
?

2、如果要在内部类B中获得其外部类A的引用,可以使用外部类的类名+.this关键字。例子如下所示:

?

public class DotThis {void f(){System.out.println("DotThis.f()");}public class Inner{public DotThis outer(){return DotThis.this;}}public Inner inner(){return new Inner();}public static void main(String[] args){DotThis dotThis = new DotThis();DotThis.Inner inner = dotThis.inner();inner.outer().f();}}

?

3、如果一个外部类A中有内部类B,并且该内部类B是嵌套类(静态内部类),则要实例化这个内部类时,不需要引用外部类的实例。例子代码如下所示:

?

public class Parcel3 {static class StaticDestination{private String label;StaticDestination(String whereTo) {this.label = whereTo;}String readLabel(){return label;}}public static void main(String[] args){Parcel3.StaticDestination staticDestination = new Parcel3.StaticDestination("Tasmania");}}

?

4、内部类可以定义在类中,也可以定义在方法中、方法的某个范围中。例子代码如下所示:

?

public class Parcel6 {   private void internalTracking(boolean b) {     if(b) {       class TrackingSlip {         private String id;         TrackingSlip(String s) {           id = s;         }         String getSlip() { return id; }       }       TrackingSlip ts = new TrackingSlip("slip");       String s = ts.getSlip();     }     // 超出内部类的定义范围,无法访问这个内部类    //! TrackingSlip ts = new TrackingSlip("x");   }    public void track() { internalTracking(true); }   public static void main(String[] args) {     Parcel6 p = new Parcel6();     p.track();   } } 

?

5、匿名内部类使用默认构造器,如果其基类的构造方法需要传参数,那么这个匿名内部类的构造方法也需要传参数。不传参数的话,编译器会报错。而且该匿名内部类看起来是继承或者实现了基类。例子代码如下所示:

?

public class Parcel8 {class Wrapping{private int x;public Wrapping(int x) {this.x = x;}int value(){return x;}}public Wrapping warrping(int x){return new Wrapping(x){@Overrideint value() {return super.value()*47;}};}}
?

6、在匿名内部类中如果该匿名内部类中需要直接引用外部类的变量,则该变量必须是final的。上例中因为没有直接在匿名内部类中引用x,只是构造方法传参数进去,因此x不需要是final的。代码例子如下所示:

?

abstract class Destination{abstract String readLabel();}public class Parcel10 {public Destination destination(final String dest,final float price){return new Destination(){private int cost;{cost = Math.round(price);if(cost>100){System.out.println("Over budget!");}}private String label = dest;@OverrideString readLabel() {return label;}};}public static void main(String[] args){Parcel10 parcel10 = new Parcel10();parcel10.destination("Tasmania", 101.95F);}}

?

7、匿名内部类有点类似于平常的继承,因为它们可以继承一个类或者实现一个接口,但是不能两者都有。如果是实现一个接口的话,只能实现一个接口。?

?

8、如果在内部类和外部类之间不需要连接的话,则可以使用嵌套类,即这个内部类是静态的(static)的。使用嵌套类意味着:

?

a、不需要使用外部类来创建一个嵌套类对象。

b、不能从嵌套类访问非静态的外部类的对象。

c、可以有静态域、静态数据。

d、嵌套类内部可以有嵌套类。

?

而普通的内部类与嵌套类相比较而言,有以下不同点:

?

a、必须通过外部类的引用来创建一个内部类的对象。

b、内部类可以访问外部类的的域、方法(静态非静态都可以)。

c、普通内部类不能定义静态域、静态方法,也不能定义嵌套类,不过可以定义常量(static final的常量)

?

9、嵌套类可以是接口的一部分。因为在接口中的所有类都默认是public和static的,所以在接口中定义嵌套类并不违反接口的规则。例子代码如下所示:

?

public interface ClassInInterface {void howdy();class Test implements ClassInInterface{@Overridepublic void howdy() {System.out.println("Test.howdy()");}public static void main(String[] args){new Test().howdy();}}}
?

?

未完待续。

读书人网 >编程

热点推荐