《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();
  
 }
}
相關文章
相關標籤/搜索