现在的位置: 首页 > 综合 > 正文

java内部类

2013年01月31日 ⁄ 综合 ⁄ 共 3290字 ⁄ 字号 评论关闭

先说明一个类名指定方式的问题。开门见山上代码!(以注释为重,多余代码忽略)

public class Parcel2 {
  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 = contents();
    Destination d = to(dest);
    System.out.println(d.readLabel());
  }
  public static void main(String[] args) {
    Parcel2 p = new Parcel2();
    p.ship("Tasmania");
    Parcel2 q = new Parcel2();
    Parcel2.Contents c = q.contents();
    Parcel2.Destination d = q.to("Borneo");
  }
}

注意:在Parcel2类内指定内部类只需用内部类名。在Parcel2外要定义内部类类型的话,必须用 [外部类名].[内部类名] 的方式。

《Thinking in Java》上说,内部类不只是一种名字隐藏和组织代码的模式。

下面就来介绍一下内部类一些其他的特性。

1、内部类拥有其外围类的所有元素的访问权。即使该类是多层的内部类,他对外面的每一层都有相同的访问权限。(这是因为在创建内部类的一个对象时候,自生成了一个外部类对象与该对象的引用,当在内部类中访问外部类成员时使用的就是该引用。而这个过程是不可见的。)

2、在内部类中使用  [外部类名].this  的方式获得外部类的引用。

public class DotThis {
  void f() { System.out.println("DotThis.f()"); }
  public class Inner {
    public DotThis outer() {
      return DotThis.this;
      // 这里使用this的话是指向Inner的。
    }
  }
  public Inner inner() { return new Inner(); }
  public static void main(String[] args) {
    DotThis dt = new DotThis();
    DotThis.Inner dti = dt.inner();
    dti.outer().f();
  }
} 

3、创建内部类对象

public class DotNew {
  public class Inner {}
  public static void main(String[] args) {
    DotNew dn = new DotNew();
    DotNew.Inner dni = dn.new Inner();
  }
}

只能通过 [外部类引用].new  [内部类名]()的方式来新建内部类对象。

4、还可以在方法中声明类,不过该类的作用范围只在该方法内。甚至在if、while等语句内也可以定义类。

public int value() {
  if(true){
	class aa{				
		}
	}
  while(true){				
       class aa{				
		}
	}			
   return i;
		}

5、接口内的内部类:默认是publicstatic。它们两者只是简单的嵌套,内部类还可以实现它外部的接口。

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

6、内部类的继承

class WithInner {
  class Inner {}
}

public class InheritInner extends WithInner.Inner {
  InheritInner(WithInner wi) {
    wi.super();
  }
  public static void main(String[] args) {
    WithInner wi = new WithInner();
    InheritInner ii = new InheritInner(wi);
  }
}

继承了内部类Inner的InheritInner类的构造函数必须入代码所示:传入外围类对象,并且调用外围类的构造函数。
7、内部类的覆盖

class Egg {
  private Yolk y;
  protected class Yolk {
    public Yolk() { System.out.println("Egg.Yolk()"); }
  }
  public Egg() {
	  System.out.println("New Egg()");
    y = new Yolk();
  }
}	

public class BigEgg extends Egg {
  public class Yolk {
    public Yolk() { System.out.println("BigEgg.Yolk()"); }
  }
  public static void main(String[] args) {
    new BigEgg();
  }
} /* Output:
New Egg()
Egg.Yolk()

BigEgg继承了Egg类,以我们以往的经验,BigEgg中的Yolk内部类会覆盖Egg类中的Yolk类,但是实际并不是如此:两个Yolk类是两个完全独立的实体,各自在各自的命名空间。可以这么说,除了类名相同外这两个类没什么联系。

但下面的这种情况可以达到我们覆盖内部类的要求

class Egg2 {
  protected class Yolk {
    public Yolk() { System.out.println("Egg2.Yolk()"); }//3-->Egg2.Yolk()  6--->Egg2.Yolk()
    public void f() { System.out.println("Egg2.Yolk.f()");}
  }
  public Egg2() { System.out.println("New Egg2()"); }//4--->New Egg2()
  private Yolk y = new Yolk();//2
  public void insertYolk(Yolk yy) { y = yy; }//7
  public void g() { y.f(); }//9
}	

public class BigEgg2 extends Egg2 {
  public class Yolk extends Egg2.Yolk {
    public Yolk() { System.out.println("BigEgg2.Yolk()"); }//7--->BigEgg2.Yolk()
    public void f() { System.out.println("BigEgg2.Yolk.f()"); }//10--->BigEgg2.Yolk.f()

  }
  public BigEgg2() { insertYolk(new Yolk()); }//5
  public static void main(String[] args) {
    Egg2 e2 = new BigEgg2();//1
    e2.g();//8
  }
} /* Output:
Egg2.Yolk()
New Egg2()
Egg2.Yolk()
BigEgg2.Yolk()
BigEgg2.Yolk.f()

通过指定内部类继承的类可以达到我们的期望。如BigEgg2中明确地指出了Yolk继承自Egg.Yolk类。代码中数字给出了运行过程

内部类的一个重要作用:使JAVA“多继承”成为可能。

8、对于类来说,只有内部类能被private关键字修饰。


抱歉!评论已关闭.