第十章 内部类

来源:互联网 发布:淘宝银色遮光布有毒吗 编辑:程序博客网 时间:2024/05/30 23:02

可以将一个类的定义放在另一个类的定义内部,这就是内部类。

1、创建内部类

package demo;public class Parec1 {     class Contents{ private int i = 11; public int value(){ return i; } }  class Destination{ private String label; Destination(String whereTo){ label = whereTo; } String readLabel(){ return label; } }  public void ship(String dest){ Contents c = new Contents(); Destination d= new Destination(dest); System.out.println(d.readLabel()); } public static void main(String[] args) {Parec1 p = new Parec1();p.ship("hello");}}

在ship()方法里面使用内部类的时候,和普通类没有什么不同。下面是一种典型的情况。

package demo;public class Parec1 {     class Contents{ private int i = 11; public int value(){ return i; } }  class Destination{ private String label; Destination(String whereTo){ label = whereTo; } String readLabel(){ return label; } } public Destination to(String s){return new Destination(s);}public Contents contents(){return new Contents();}  public void ship(String dest){ Contents c = new Contents(); Destination d= new Destination(dest); System.out.println(d.readLabel()); } public static void main(String[] args) {Parec1 p1 = new Parec1();p1.ship("hello");Parec1 p2 = new Parec1();Parec1.Contents c = p2.contents();Parec1.Destination d = p2.to("world");System.out.println(d.label);}}

  如果想从外部类的非静态方法之外的任意位置创建某个内部类的对象,就必须让main()方法中一样,使用OutClassName.InnerClassName.(这两段代码的差别)


2、链接到外部类

     当生成内部类对象的时候,此对象与制造它的外围类之间就有了一种联系,所以它能访问其外围对象的所有成员,而不需要任何条件。此外,内部类还拥有其外围类的所有元素的访问权。

package demo;interface Selector{boolean end();Object current();void next();}public class Sequence {    private Object[] items ;    private int          next = 0 ;        public Sequence (int size){    items = new Object[size];    }    public void add(Object x){if(next<items.length){items[next++] = x ;}}private class SequenceSelector implements Selector{        private int i = 0 ; @Overridepublic boolean end() {return i == items.length;}@Overridepublic Object current() {return items[i];}@Overridepublic void next() {if(i < items.length){ i++;}}}public Selector slelctor(){return new SequenceSelector();}public static void main(String[] args) {Sequence sequence = new Sequence(10) ; for (int i = 0 ; i<10 ; i++){sequence.add(Integer.toString(i));}Selector selector = sequence.slelctor();while(!selector.end()){System.out.println(selector.current()+" ");selector.next();}}}
    当外围类对象创建了一个内部类的对象时,此内部类对象必定会秘密地捕获一个指向那个外围类对象的引用,然后当你访问外类的成员时,就是用那个引用来选择外围类的成员。编译器会帮忙处理这些细节,但你现在可以看到:内部类的对象只能在与其外围类对象相关联的情况下才能被创建(就像你看到就像内部类是非static类时)。创建内部类对象时,需要一个指向其外围类对象的引用,如果编译器访问不到这个引用就会报错。不过绝大部分时候都不无需程序员操心。


10.3 使用.this与.new
    如果你希望生成对外部类对象的引用,可以使用外部类的名字后面紧跟圆点和this。这样产生的引用自动地具有正确的类型,这一点在编译器就被知晓并收到检查,因此没有任何运行时开销。

package demo;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) {// TODO Auto-generated method stubDotThis dt = new DotThis();DotThis.Inner dti = dt.inner();        dti.outer().f();}}
 有时候你可能想去告诉其他对象,去创建某个内部类的对象,要实现此目的就要使用.new

package demo;public class DotNew {public class Inner{}public static void main(String[] args) {// TODO Auto-generated method stub        DotNew dn = new DotNew ();        DotNew.Inner dni = dn.new Inner();}}
  想要直接创建内部类对象,你不能按照你想想的方式,去引用外部类的名字DotNew,儿是必须使用外部类的对象来创建该内部类的对象,就像上面的程序看到的一样。因此不必声明(实际上不能声明)dn.new DotNew.Inner();






0 0
原创粉丝点击