美文网首页
内部类(完整版)--来自Java编程思想

内部类(完整版)--来自Java编程思想

作者: 998584f56259 | 来源:发表于2016-09-29 18:52 被阅读68次

1、创建内部类

// 创建一个内部类
public class Parcel1 {
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) {
  Parcel1 p = new Parcel1();
  p.ship("Tasmania");
}
} 

2、相比普通用法,更典型的情况是,外部类将有一个方法,该方法返回一个指向内部类的引用。

//返回一个内部类的引用:外部类提供返回内部类引用的方法
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();
  Contents c = q.contents();
  Destination d = q.to("Borneo");
}
}  

如果想从外部类的非静态方法之外的任意位置创建某个内部类的对象,那么必须具体地指明这个对象的类型:OuterClassName.InnerClassName。

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

//内部类持有外部类对象的引用,因此,内部类拥有其外围类所有元素的访问权
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;
   public boolean end() { return i == items.length; }
   public Object current() { return items[i]; }
  public void next() { if(i < items.length) i++; }
}

/**
 * 外部类方法返回内部类对象引用
 */
public Selector selector() {
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.selector();
  while(!selector.end()) {
    System.out.print(selector.current() + " ");
    selector.next();
}
}
}  

内部类可以访问其外围类的方法和字段,不管是否是private成员,它就像自己拥有它们似的,这带来了很大的方便。

4、如果你需要在内部类中生成对外部类对象的引用,可以使用外部类的名字后面紧跟原点和this。这样引用自动地具有正确的类型,这一点在编译期就被知晓并受到检查,因此没有任何运行时开销。

 //内部类中生成外部类的引用
 public class DotThis {
 void f() { System.out.println("DotThis.f()"); }

 public class Inner {
   public DotThis outer() {
     return DotThis.this;
    // 只有指明了外部类名.this,返回的引用才是外部类对象的引用
    //如果只是返回this,这个指代的是内部类对象的引用
}
}
public Inner inner() {
  return new Inner(); 
}
public static void main(String[] args) {
DotThis dt = new DotThis();
Inner dti = dt.inner();
dti.outer().f();
}
}  

5、要想使用new关键字创建内部类对象,必须使用外部类的对象来创建该内部类对象,因此,在拥有外部类对象之前是不可能创建内部类对象的。内部类的对象会暗暗地连接到创建它的外部类对象上。

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

6、局部内部类

//局部类
public class Parcel5 {
public Destination destination(String s) {
class PDestination implements Destination {
  private String label;
  private PDestination(String whereTo) {
    label = whereTo;
  }
  public String readLabel() { return label; }
}
return new PDestination(s);
}

public static void main(String[] args) {
Parcel5 p = new Parcel5();
Destination d = p.destination("Tasmania");
}
}

7、匿名内部类

//返回一个匿名类的实例
public class Parcel7 {
public Contents contents() {
return new Contents() { // 嵌入一个类的定义
  private int i = 11;
  public int value() { return i; }
}; // 在这里需要分号结束
}
public static void main(String[] args) {
Parcel7 p = new Parcel7();
Contents c = p.contents();
}
} 

contents()方法将返回值的生成与表示这个返回值的类的定义结合在 一起,另外,这个类是匿名的,它没有名字。看起来似乎是要创建一个contents对象,实际创建的是一个继承自Contents的匿名类的对象。

8、如果定义一个匿名内部类,并且希望它使用一个在其外部类定义的对象,那么编译器会要求其参数引用是final的。

public class Parcel9 {
   public Destination destination(final String dest) {
     return new Destination() {
     private String label = dest;
     public String readLabel() { return label; }
};
}
  public static void main(String[] args) {
  Parcel9 p = new Parcel9();
  Destination d = p.destination("Tasmania");
}
}  

8、嵌套类
如果不需要内部类对象与其外围类对象之间有联系,那么可以将内部类声明 为static。这通常称为嵌套类,也叫静态内部类。要创建嵌套类的对象, 并不需要其外围类的对象,不能从嵌套类的对象中访问非静态的外围类的 对象。除此之外,普通内部类的字段与方法,只能放在类的外部层次上,所以 普通的内部类不能有static数据和static字段,也不能包含嵌套类。

//静态内部类
public class Parcel11 {

private static class ParcelContents implements Contents {
private int i = 11;
public int value() { return i; }
}

protected static class ParcelDestination implements Destination {
private String label;
private ParcelDestination(String whereTo) {
  label = whereTo;
}
public String readLabel() { return label; } 
public static void f() {}
static int x = 10;
static class AnotherLevel {
  public static void f() {}
  static int x = 10;
}
}

public static Destination destination(String s) {
return new ParcelDestination(s);
}

public static Contents contents() {
return new ParcelContents();
}

public static void main(String[] args) {
Contents c = contents();
Destination d = destination("Tasmania");
}
} 

相关文章

网友评论

      本文标题:内部类(完整版)--来自Java编程思想

      本文链接:https://www.haomeiwen.com/subject/eqclyttx.html