Java编程思想(2nd)学习笔记(8)-2

类别:Java 点击:0 评论:0 推荐:

二.     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();

            }

        }

    }

}      

本文地址:http://com.8s8s.com/it/it17097.htm