二.     Inner classes(内隐类) 
1.  内隐类的基本用法 
1)        如果要在外围class的non-static函数之外产生一个inner class对象,得以OuterClassName.InnerClassName的形式指定该对象的型别。而在non-static函数内则不用。 
public class ExplicitStatic{ 
    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){ 
    //在outer class的non-static函数中可直接产生inner class对象 
        return new Destination(s); //(1) 
    } 
    public Contents cont(){ 
        return new Contents(); //(1) 
    } 
    public void ship(String dest){ 
//在outer class的non-static函数中可直接通过InnerClassName 
//来指定对象型别 
        Contents c = cont(); 
        Destination d = to(dest); 
        System.out.println(d.readLabel()); 
    } 
    public static void main(String[] args){ 
        ExplicitStatic p = new ExplicitStatic(); 
        p.ship("Tanzania"); 
        ExplicitStatic q = new ExplicitStatic(); 
   //在outer class的非non-static函数内产生inner class对象 
        ExplicitStatic.Contents c = q.cont(); 
        ExplicitStatic.Destination d = q.to("Borneo"); 
  //不能在static函数直接生成inner class对象 
// new Contents(); 
    } 
} 
2)        对于non-static inner class,在外围class的non-static函数可以通过new产生一个inner class对象,如上面的(1)处。但要在非non-static函数产生一个inner class对象,则一定要关联到其enclosing class的某个对象。 
3)        inner class的向上转型 
当把一个inner class对象向上转型成为interface时,我们得到的只是一个reference。 
interface Destination{ 
    String readLabel(); 
} 
interface Contents{ 
    int value(); 
} 
class Parcel3{ 
    private class PContents implements Contents{ 
        private int i = 11; 
        public int value() { return i; } 
    } 
    protected class PDestination implements Destination{ 
        private String label; 
        PDestination(String whereTo){ 
            label = whereTo; 
        } 
        public String readLabel() { return label; } 
    } 
    public Destination to(String s){ 
        return new PDestination(s); 
    } 
    public Contents cont(){ 
        return new PContents(); 
    } 
} 
public class ExplicitStatic{     
    public static void main(String[] args){ 
        Parcel3 p = new Parcel3(); 
        //把inner class对象向上转型 
        Contents c = p.cont(); 
        Destination d = p.to("Borneo");         
    } 
} 
虽然我们不能在ExplicitStatic class无法调用Pcontents class,但我们把一个Pcontents class对象向上转型为Contents,就可对之进行调用。 
4)        inner class的作用域为定义该inner class的scope内。但inner class可在它的作用域之外被继承(见4)。 
interface Contents{ 
    int value(); 
} 
class Parcel3{ 
    //PContents1 class的作用域为Parcel3 class内 
    private class PContents1 implements Contents{ 
        private int i = 11; 
        public int value() { return i; } 
    } 
    public Contents cont1(){ 
        return new PContents1(); 
    } 
    public Contents cont2(){ 
        //PContents2 class的作用域为函数cont2内 
        class PContents2 implements Contents{ 
            private int i = 11; 
            public int value() { return i; } 
        } 
        return new PContents2(); 
    } 
    //不能在函数cont2外使用PContents2 class 
    /* 
    public Contents cont22(){ 
        return new PContents2(); 
    } 
    */ 
    public Contents cont3(boolean b){ 
        if(b){ 
            //PContents3 class的作用域为当前if内 
            class PContents3 implements Contents{ 
                private int i = 11; 
                public int value() { return i; } 
            } 
            return new PContents3(); 
        } 
        //不能在if外使用PContents3 class 
        //return new PContents3(); 
        return null; 
    }  
} 
public class ExplicitStatic{     
    public static void main(String[] args){ 
        Parcel3 p = new Parcel3(); 
        Contents c1 = p.cont1(); 
        Contents c2 = p.cont2(); 
        Contents c3 = p.cont3(true); 
    } 
} 
2.  内隐类与外围enclosing  class的连接关系 
2.1 non-static inner class 
1)        inner class可以访问enclosing class的所有成员(包括private成员),就像inner class自己拥有这些成员一样。即inner class天生具有对enclosing class的所有成员的访问权力。 
2)        Inner class对象被产生时,一定要关联到其enclosing class的某个对象(这个enclosing class对象就是Inner class对象的制造者)。建构inner class对象的同时,得有其enclosing class对象的reference才行。 
原因:因为inner class可以访问enclosing class的所有成员,那么当产生一个inner class时,编译器会自动为inner class对象添加一个指向enclosing class对象的reference(这个reference是隐藏的)。所以Inner class被产生时,一定要关联到其enclosing class的某个对象。 
3)        同一个enclosing class对象产生出来的inner class对象访问的是同一个enclosing class对象中的成员。 
interface Destination{ 
    String readLabel(); 
} 
interface Contents{ 
    int value();     
} 
class Parcel3{ 
    int i1 = 10; 
    private String s1 = "Parcel3_"; 
    Parcel3(String s){ 
        s1 += s; 
    } 
    private class PContents implements Contents{ 
        //可调用enclosing class的成员 (1) 
        private int i2 = i1; 
        private String s2 = s1; 
        PContents(int num){ 
         System.out.println("" + num + ": i2 = " + i2 + ",s2 = " + s2); 
        } 
        public int value() { return 1; } 
    } 
    public Contents cont(int i){ 
        return new PContents(i); 
    } 
} 
public class ExplicitStatic{     
    public static void main(String[] args){ 
        Parcel3 p1 = new Parcel3("1"); 
        Contents c1 = p1.cont(1);         
        Contents c2 = p1.cont(2); 
        Parcel3 p2 = new Parcel3("2"); 
        c2 = p2.cont(3); 
        c2 = p1.cont(4); 
    } 
} 
结果为: 
1: i2 = 10,s2 = Parcel3_1 
2: i2 = 10,s2 = Parcel3_1 
3: i2 = 10,s2 = Parcel3_2 
4: i2 = 10,s2 = Parcel3_1 
在(1)在inner class调用了enclosing class的成员。结果表明,同一个enclosing class对象p1产生的inner class对象调用的是同一个enclosing class对象中的成员,如结果中的1、2、4。 
              2.2  Static inner classes(静态内隐类) 
1)  产生Static inner classes对象时,不需要同时存在一个enclosing class对象 
2)  只能在Static inner classes对象中访问enclosing class中的静态成员。 
interface Contents{ 
    int value();     
} 
class Parcel1{  
private static String s1 = "Parcel3_"; 
private String s11 = “Parcel3_”; 
    Parcel1(String s){ 
        s1 += s; 
    } 
protected static class PContents implements Contents{  
//只能访问enclosing class中的s1 
        String s2 = s1; 
//s11不是static成员,不能访问 
//String 22 = s11; 
        PContents(int num){ 
            System.out.println("" + num + ":s2 = " + s2); 
        } 
        public int value() { return 1; } 
    } 
    public static  Contents cont(int i){ 
        return new PContents(i); 
    } 
} 
public class ExplicitStatic{     
    public static void main(String[] args){ 
        Parcel1 p1 = new Parcel1("1"); 
        Contents c1 = p1.cont(1);    
        c1 = Parcel1.cont(2);  //(1) 
        Parcel1 p2 = new Parcel1("2"); 
        c1 = p2.cont(3); 
        c1 = Parcel1.cont(4); //(1) 
    } 
} 
因为内隐类Pcontents class是静态的,所以在(1)处不通过enclosing class对象而是通过静态函数来直接产生其对象。 
2.3       无论inner class被嵌套置放的层次有多深,且所有outer class的成员都可 
被它访问。 
class MNA{ 
    private void f() {} 
    class A{ 
        private void g() {} 
        class B{ 
            void h(){ 
                g(); 
                f(); 
            } 
        } 
    } 
}         
 
  |