您的位置:首页 > 其它

内部类一

2015-10-24 20:03 162 查看
关于java的内部类,尤其匿名类,会感到无法理解,下文简单实验总结一下。由于内部类涉及很多知识,其中很多没有涉及到。如有表述代码错误,欢迎读者指正!
那为什么使用内部类呢?《thinking in java》第十章中,指出:一般来说,内部类继承自某个类或实现某个接口,内部类的代码操作创建它的外围类的对象,所以可以认为内部类提供了某些进入其外围类的窗口。其最吸引之处,每个内部类都能独立的继承自一个(接口的)实现,所以无论外围类是否已经继承了某个(接口的)实现,对于内部类都没有影响。

内部类和接口可以实现c++中的多继承的作用效果。

简单内部类:

点击(此处)折叠或打开

public class Parcell1 {

private int i = 5;

 

class Contents{

private int i = 1;

public int value(){ return Parcell1.this.i;}

}

class Destination{

private String label;

private int i = 6;

Destination(String whereTo){

label = whereTo;

}

String readLabel(){ return label;}

public void ship(String dest){

Contents c = new Contents();

System.out.println(value());

Destination d = new Destination(dest);

System.out.println(d.readLabel());

}

public static void main(String[] args){

Parcell1 p = new Parcell1();

p.ship("wang");

}

}

上面Contents,Destination类在Parcell1内部,Parcell1对象通过调用函数ship,创建了两内部类的对象,然后通过调用内部类的函数,打印出私有域的值。上述看以看出这两个内部类就如外部类的成员一样,逻辑结构比较简单,我把这种内部类称之为简单内部类,当然也可称成员内部类,同理它可以被权限修饰词修饰,如果是private,则只能在外部类内部被访问,若是public,则可以在任意地方被访问,若是protected,则只能在包内和其子类访问,和普通的类成员没有区别。

要注意的是,在内部类Contents中,打印的是外围类的私有域值,由于内部类可以引用外围类的成员变量及方法,引用格式:

局部内部类:

顾名思义,这种类定义在方法内或者域内,而且它的作用域也局限于方法和域内,不能被访问权限修饰词所修饰。

点击(此处)折叠或打开

interface pr { 

    

    void print1(); 

    

    }

点击(此处)折叠或打开

public class Parcell2 {

    

    private int i = 5;

    public pr ship(String wang){

    class Destination implements pr {

        

        private String label;

        private int i = 6;

        

        Destination(String whereTo){

            

         label = whereTo;

         RetrunLabel();

        }

        public void print1() {

            

            System.out.println(label);

        }

     

        public void RetrunLabel(){

            

            System.out.println(label);

        }

    }

    return new Destination(wang);

}

        

        

    public static void main(String[] args){

        

        Parcell2 p = new Parcell2();

        pr wang = p.ship("wang");

    }

}

上面局部类放在返回值是接口对象类型的函数中,该类继承了该接口,该题只是简单的打印出了内部类的私有域,其中可以自定义很多内容,读者感兴趣可以尝试。

静态内部类:

如果我们把内部类看成是外部类的成员,则并不矛盾。静态内部类不能只想外部类的引用,而且在任何非静态内部类中,都不能有静态数据,静态方法或者又一个静态内部类(内部类的嵌套可以不止一层)。不过静态内部类中却可以拥有这一切。

点击(此处)折叠或打开

public class Parcell3 {

    

    private int i = 5;

   static class Destination{

        

        private String label;

        private static int i = 5;

        //private static int j = 6; //error if the class is not static 

        Destination(String whereTo){

            

            label = whereTo;

        }

        

        int readi(){ return i;} //Parcell3.this.i;
error

        

    }

    

    public void ship(String dest){

        

        Destination d = new Destination(dest);

        System.out.println(d.readi());

    

    }

    public static void main(String[] args){

        

        Parcell3 p = new Parcell3();

        p.ship("wang");

        

    }

}

匿名类:

匿名类是不能有名称的类,所以没办法引用他们。必须在创建时,作为new语句的一部分来声明他们。 

这就要采用另一种形式 的new语句,如下所示: 

        new <类或接口> <匿名类的主体>

        这种形式的new语句声明一个 新的匿名类,他对一个给定的类进行扩展,或实现一个给定的接口。他还创建那个类的一个新实例,并把他作为语句的结果而返回。要扩展的类和要实现的接口是 new语句的操作数,后跟匿名类的主体。

点击(此处)折叠或打开

public interface prr {

   

    String print1();

    String geti();

}

点击(此处)折叠或打开

public class Parcell4 {

    

    private int i = 5;

    private String ss;

    

     Parcell4(String ss){

         

         this.ss = ss;

     }

     

    public prr ship(String qq){

        

    return new prr(){

        

        public String print1() {

            

            return ss + qq;

        }

    

        public String geti(){

            

            return "Lios" + "\n" +i;

        }

    };

    

}

        

    public static void main(String[] args){

        

        Parcell4 p = new Parcell4("diy_");

        prr c = p.ship("os");

        String s = p.ship("os").print1();

        System.out.println(s);

        System.out.println(c.geti());

        

    }

}

上面我们不知道一个匿名类的名字,而return new prr()这一句很让人寻味,好像在实例化一个prr对象(接口是高级抽象类,当然不能被实例化),但是此时又恰好创建一个类,但是我们无法知道它的名字。

我们把上面的匿名内部类改成一般形式:

点击(此处)折叠或打开

package 第十章内部类;

public interface prr {

   

    String print1(String bb);

    String geti();

}

点击(此处)折叠或打开

public class Parcell5 {

    

    private int i = 5;

    private String ss;

    

     Parcell5(String ss){

         

         this.ss = ss;

     }

     

    class WANG implements prr{

        

        public String print1(String bb) {

            

            return ss + bb;

        }

    

        public String geti(){

            

            return "Lios" + "\n" +i;

        }

    }

        

    public prr ship(){

        

        return new WANG();

    }

    

    public static void main(String[] args){

        

        Parcell5 p = new Parcell5("diy_");

        prr c = p.ship();

        String s = p.ship().print1("os");

        System.out.println(s);

        System.out.println(c.geti());

        

    }

}

我们发现使用抽象类很简洁,但是要注意几点:

1.匿名内部类是没有访问修饰符的。

2.new 匿名内部类,这个类(接口)首先是要存在的。

3.匿名内部类是没有构造方法。

文章参考:
点击打开链接点击打开链接

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: