Java学习个人备忘录之内部类

内部类: 将一个类定义在另一个类的里面,对里面那个类就称为内部类.  

class Outer  
{  
    private int num = 3;  
    class Inner //它想访问Outer中的num, 如果在外面就需要创建一个对象,然后通过公开的接口访问,但是现在Outer内部, 就可以直接访问了.这样方便  
    {  
        void show()  
        {  
            System.out.println("show run..." + num);  
        }  
    }  
    //如果现在想访问Inner就需要这样  
    public void method()  
    {  
        Inner in = new Inner();  
        in.show();  
    }  
    //内部类由于在内部, 相当于定义在了成员的位置上, 所以可以用成员修饰符, 如:  
    //private class Test{}  
    static class Inner  
    {  
        static void function()  
        {  
            System.out.println("function run......"+num);  
        }  
    }  
}

 

内部类访问特点:
1. 内部类可以直接访问外部类中的成员.
2. 外部类要访问内部类, 必须建立内部类的对象.

一般用于类的设计。

分析事物时, 发现该事物描述中还有事物,而且这个事物还在访问被描述事物的内容。
这时就把还有的事物定义成内部类来描述。

class InnerClassDemo  
{  
    public static void main(String[] args)  
    {  
        Outer out  = new Outer();  
        out.method();  
        //直接访问外部类中的内部类中的成员.  
        Outer.Inner in = new Oouter().new Inner();  
        in.show();  
        //如果内部类是静态, 那就相当于一个外部类了.  
        Outer.Inner in = new Outer.Inner();  
        in.show();  
        //如果内部类是静态的,成员是静态的.  
        Outer.Inner.function();  
 
        //如果内部类中定义了静态成员,该内部类也必须是静态的.  
  
    }  
}  

 

细节

class Outer  
{  
    int num = 3;  
    class Inner  
    {  
        int num = 4;  
        void show()  
        {  
            int num = 5;  
            System.out.println(num);//5  
            System.out.println(this.num);//4  
            System.out.println(Outer.this.num);//3  
        }  
    }  
    void method()  
    {  
        new Inner().show();  
    }  
}  

class InnerClassDemo2  
{  
    public static void main(String[] args)  
    {  
        new Outer().method();  
    }  
}  

为什么内部类能直接访问外部类中成员呢?
那是因为内部类持有了外部类的引用-----外部类名.this

 

内部类可以存放在局部位置上

class Outer  
{  
    int num = 3;  
    Object method()  
    {  
        final int x = 9;  
        class Inner  
        {  
            void show()  
            {  
                System.out.println("show..."+num);  
            }  
        }  
        Object in = new Inner();  
        return in;//0x0045  
    }  
}  
class InnerClassDemo3  
{  
    public static void main(String[] args)  
    {  
        Outer out = new Outer();  
        Object obj = out.method();//0x0045  
    }  
}

内部类在局部位置上只能访问局部中被final修饰的局部变量。

 

匿名内部类, 就是内部类的简写格式.
必须有前提:
内部类必须继承或者实现一个外部类或者接口.

匿名内部类: 其实就是一个匿名子类对象.

格式: new 父类or接口(){子类内容}

abstract class Demo  
{  
    abstract void show();  
}  

class Outer  
{  
    int num = 4;  
    class Inner extends Demo //这是正常情况  
    {  
        void show()  
        {  
            System.out.println("show...."+num);  
        }  
    }  
    public void method()  
    {  
        new Demo()//这个就叫匿名内部类  
        {  
            void show()  
            {  
                System.out.println("show...."+num);  
            }  
        }  
    }  
}

 

匿名内部类的应用

interface Inter  
{  
    void show1();  
    void show2();  
}  

class Outer  
{  
    public void method()  
    {  
        new Inter()  
        {  
            public void show1()  
            {}  
            public void show2()  
            {}  
        }.show1();  //调用了show1的方法, 相当于  new Inner().show1();  
          
        //或者用下面的方法  
        Inter in = new Inter()  
        {  
            public void show1()  
            {}  
            public void show2()  
            {}  
        }  
        in.show1();  
        in.show2();  
    }  
}  

 

通常的使用场景之一:
当函数参数是接口类型时,而且接口中的方法不超过三个.
可以用匿名内部类作为实际参数进行传递.

class InnerClassDemo5  
{  
    public static void main(String[] args)  
    {  
        show(new InterImpl());  
    }  
    public static void show(Inter in)  
    {  
        in.show1();  
        in.show2();  
    }  
}  
class InterImpl implements Inter  
{
}  

 

对象的初始化过程

class Fu  
{  
    int num = 9;  
    {  
        System.out.println("Fu");  
    }  
  
  
    Fu()  
    {  
        super();  
        //显示初始化  
        //构造代码块初始化  
        show();  
    }  
    void show()  
    {  
        System.out.println("fu show..."+num); //被覆盖,运行子类  
    }  
}  
class Zi extends Fu  
{  
    int num = 8;  
    {  
        System.out.println("Zi");  
    }  
    Zi()  
    {  
        super();  
        //显示初始化  
        //构造代码块初始化  
        show();  
    }  
    void show()  
    {  
        System.out.println("zi show..."+num);  
    }  
}  
  
  
class Inner  
{  
    public static void main(String[] args)  
    {  
        new Zi();  
    }  
}
/*
Fu
zi show...0
Zi
zi show...8
*/

 

posted @ 2017-09-04 18:10  Y_zr  阅读(147)  评论(0编辑  收藏  举报