《Thinking in Java》Ten 内部类

内部类:将一个类的定义放在另外一个类的定义内部。java

建立内部类:设计模式

//内部类
class Outer{
 class Inner{
 {System.out.println("Inner class");}
 
 public void print(){
  System.out.println("Inner print()");
 }
}
 public Inner inMethod(){
  return new Inner();
 }
}
public class OuterInnerTest {
  
  public static void main(String[] args){
   Outer out = new Outer();
  
   //从外部类的非静态方法以外的任意位置建立某个内部类的对象,必须具体地
  
   //指明这个对象:OuterClassName.InnerClassName。
  
   Outer.Inner in = out.inMethod();
   in.print();
  }
}

内部类自动拥有对其外围类全部成员的访问权。当外围类的对象建立了一个内部类对象时,此内部类对象会捕获一个指向外围类对象的引用。这样,在内部类访问外围类的成员时,是所捕获的引用在操纵内部类成员。this

package Ten;
interface Selector{
 boolean end();
 Object current();
 void next();
 Sequence sequ();
}
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;
 }
 
 class StringHolder{
  String str;
  
  StringHolder(String str){
   this.str = str;
  }
  
  public String toStr(){return str;}
 
 }

 //内部类 其中的三个方法都用到了外围类的items,说明内部类自动拥有对其外围类的全部成员的访问权

 private class SequenceSelector implements Selector{
  private int i = 0;
  public boolean end() {
   // TODO Auto-generated method stub
   return i == items.length;
  }
  public Object current() {
   // TODO Auto-generated method stub
   return items[i];
  }
  public void next() {
   // TODO Auto-generated method stub
   if(i < items.length)
    i++;
  }
  public Sequence sequ() {
   // TODO Auto-generated method stub
  
   return Sequence.this;//生成外部类的引用

  }
  
 }

 //迭代器设计模式

 public Selector selector(){
  return new SequenceSelector();
 }
 
 public static void main(String[] args){

  //建立内部类对象,此内部类对象会捕获一个指向外围类的引用,当访问外围类成员时就是用这个引用来访问

  Sequence sequence = new Sequence(10);
  for(int i=0;i<10;i++)
   /*String java.lang.Integer.toString(int i)
Returns a String object representing the specified integer.
*/
   //sequence.add(Integer.toString(i));
   sequence.add(sequence.new StringHolder(Integer.toString(i)));

  Selector selector = sequence.selector();//内部类访问外围类的方法
 
  while(!selector.end()){
   System.out.print(selector.current() + " ");
   selector.next();
  }
 }
}/*0 1 2 3 4 5 6 7 8 9 */

.this、.newspa

能够使用外围类的名字加.this生成对外围类对象的引用。设计

package Ten;
class Outer3{
 class Inner3{
  Inner3(){
   System.out.println("Inner3");
  }
 }
 
 Outer3 outer(){

  return Outer3.this;//生成外部类的引用能够使用外部类的名字加.this

 }
}
public class OuterInner {
 public static void main(String[] args){
  Outer3 out3 = new Outer3();
  System.out.println(out3.outer());
  
  Outer3.Inner3 in3 = out3.new Inner3();//内部类对象的引用的建立方法
 
 }
}

在方法和做用域中的内部类code

在做用域中的内部类:对象

 package Ten;
public class ZuoyongyuInner {
 private void internal(boolean b){
  if(b){
 
   //在做用域内定义内部类
   
   class Track{
    private String id;
    Track(String s){
     id = s;
    }
    String getTrack(){return id;}
  
   }//在做用域外内部类Track是不可用的
   
   Track tc = new Track("Track");
   String s = tc.getTrack();
  }
 }
 
 public void track(){internal(true);}
 
 public static void main(String[] args){
  ZuoyongyuInner zyi = new ZuoyongyuInner();
  zyi.track();
 }
}

exercise11接口

建立一个private内部类实现一个public接口,写一个方法返回此private内部类的引用,并将此引用向上转型为接口类型,尝试向下转型说明此内部类被彻底隐藏了。ci

 package Ten;
class C{
 private class D implements B{
  public void f() {
   // TODO Auto-generated method stub
   System.out.println("Inner class D f()");
  }}
 
 public B Dm(){
  return new D();

 }//返回此private内部类的引用,并将此引用向上转型为接口类型

}
public class PrivateInner {
 public static void main(String[] args){
  C c = new C();
  c.Dm().f();
  //D d = new D(); Dcannot be resolved to a type

  //D被彻底隐藏了

 }
}/*Inner class D f()*/

匿名内部类作用域

即没有名字的内部类。匿名内部类的分号;不是标记此内部类的结束,标记的是表达式的结束,只不过此表达式包含了匿名内部类。
Exercise13.

package Ten;
public class Exise13 {
 public B b(){
  return new B(){
   public void f() {
    // TODO Auto-generated method stub
    System.out.println("Anonymous class Exise13.B()");
   }
   
  }; //
 }
 public static void main(String[] args){
  Exise13 e = new Exise13();
  e.b().f();
 }
}/*Anonymous class Exise13.B()*/

Exercise15.

建立一个拥有含有参数的构造器的类,接着建立第二个类包含一个返回第一个类的对象的引用的方法

package Ten;
class NonDeCnstr{
 String str;
 NonDeCnstr(String str){
  this.str = str;
  System.out.println(str);
 }
 public void f(){System.out.println("NonDeCnstr f()");}
}
class ReturnNon{
 public NonDeCnstr nondec(String str){
  
  //返回第一个类的引用
 
  return new NonDeCnstr(str){
   public void f(){System.out.println("ReturnNon f()");}
  };
 }
}
public class Excise15{
 public static void main(String[] args){
  ReturnNon r = new ReturnNon();
  r.nondec("ABC").f();
 }
}/*
ABC
ReturnNon f()*/

 

package Ten;
public class ReturnAnonymous {

 //contents()是返回值为接口Contents类型的方法

 public Contents contents(){
  return new Contents(){
   private int i = 11;
   public int value(){
    return i;
   }
  
  };匿名内部类的;不是标记此内部类的结束,标记的是表达式的结束,只不过此表达式包含了匿名内部类。

 }
 public static void main(String[] args){
  ReturnAnonymous re = new ReturnAnonymous();
  Contents c = re.contents();
 }
}

用匿名内部类实现工厂方法

package Ten;

//用匿名内部类实现工厂方法丢硬币

interface Toss{
 boolean b();
}
interface TossFactory{
 Toss getToss();
}
class Coin implements Toss{
 int EVENT = 2;
 private  int events = 1;
 boolean b1;
 public boolean b() {
  // TODO Auto-generated method stub
  System.out.println("Coin event :"+ events);
  return (events++ != EVENT);
 }

 //匿名内部类 

 public static TossFactory factoy = new TossFactory(){
  public Toss getToss() {
   // TODO Auto-generated method stub
   return new Coin();
  }
 };
}
public class FactoryCoin {
 public static void play(){
  Coin c = new Coin();
  while(c.b())
   ;
 }
 public static void main(String[] args){
  FactoryCoin fc = new FactoryCoin();
  fc.play();
 }
}

嵌套类

类中包含类...

package Ten;
public class QianTao {
 private static class QianTao1{
  private int i ;
  public int value(int i){
   this.i = i;
   QianTao1 q1 = new QianTao1();
   System.out.println(q1.getClass() +" value: "+ i);
   return i;
  }
  
  //内部类中又包括内部类
 
  private class QianTao2{
   private int i ;
   public int value(int i){
    this.i = i;
    QianTao2 q2 = new QianTao2();
    System.out.println(q2.getClass() + " value: "+ i);
    return i;
   }
  }
 }
 
 public static void main(String[] args){
  QianTao1 q1 = new QianTao1();
  q1.value(1);
  
  //QianTao2对外部方法不能直接Access
 
  QianTao1.QianTao2 q2 = q1.new QianTao2();
  q1.value(2);
 }
}/*
class Ten.QianTao$QianTao1 value: 1
class Ten.QianTao$QianTao1 value: 2*/

exercise19

建立一个包含内部类的类,而此内部类中又包含内部类,编译器生成了每个类的.class文件

 package Ten;
public class NestClass {
 class Inner1{
 
  class Inner2{
   void f(){}
  }
  Inner2 makeInner2(){return new Inner2();}
 }
 Inner1 makeInner1(){return new Inner1();}
 static class Nested1{
  void f(){}
 
  static class Nested2{
   void f(){}
  }
 }
 
 public static void main(String[] args){
  new NestClass.Nested1().f();
  new NestClass.Nested1.Nested2().f();
  NestClass n = new NestClass();
  NestClass.Inner1 n1 = n.makeInner1();
  NestClass.Inner1.Inner2 n2 = n1.makeInner2();
  n2.f();
  
 }
 
 }/*不是输出
生成的.class文件
NestClass.class
NestClass$Inner1.class
NestClass$Inner1$Inner2.class
NestClass$Nested1.class
NestClass$Nested1$Nested2.class
*/

包含内部类的接口

 package Ten;

//建立包含嵌套类的接口

public interface InterfaceQian {
 public void f();
 public static class A implements InterfaceQian{
  
  public void f() {
   // TODO Auto-generated method stub
   System.out.println("A f()");
  }
  public static void main(String[] args){
   A a = new A();
   a.f();
  }
 } 
}/*A f()*/

由实现接口的类间接返回接口

package Ten;
interface interf{
 void f();
}
class A{
 public interf get(){
  
  class Inf implements interf{
   public void f() {
    // TODO Auto-generated method stub
    System.out.println("Inf.f()");
   }
   
  }
  return new Inf();
  
 }
}
public class InterfaceInner {
 public static void main(String[] args){
  A a = new A();
  
  interf intf = a.get();//由实现接口的类间接返回接口
  
  intf.f();
  
 }
}
相关文章
相关标签/搜索