内部类

内部类访问特点:

1、内部类可以直接访问外部类中的成员

2、外部类要访问内部类,必须建立内部类的对象

class Outer
{
    private int num=3;
    class Inner //内部类
    {
        void show()
        {
            System.out.println("show run..."+num);//直接访问
        }
    }
    public void method()
    {
        Inner in =new Inner();//需要创建内部类的对象
        in.show();
    }
}

一般用于类的设计

分析事物时,发现该事物描述中还有事物,而且这个事物还在访问被描述事务的内容。

这时就把还有的事物定义成内部类来描述。

先说明一下static ,随着类的加载,static 变量首先被加载进内存! 

class Outer
{
    private static int num =3;
    static class Inner //内部类
    {
        void show ()
        {
            System.out.println("show run..."+num);
        }
        static void function ()//如果该内部类中定义了静态成员,这个内部类必须是静态的。
        {
            System.out.prtintln("function"+num);
        }
    }
public void method ()   
{
    Inner in =new Inner();
    in.show();

}
}
class InnerClassDemo
{
    public static void main (String[] args)
    {
        //Outer out =new Outer();    
        //out.method();
        //直接访问外部类中的内部类中的成员
        //Outer.Inner in =new Outer().new Inner();
        //in.show();
        
        //如果内部类是静态的。相当于一个外部类
        Outer.Inner in =new Outer.Inner();
        in.show();
        //如果内部类时静态的,成员是静态的,则:
        Outer.Inner.function();
            
        

    }
}

为什么内部类能直接访问外部类中的成员呢?

那是因为内部类持有了外部类的引用。 调用方法:外部类名.this.成员名

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

    }
    void method ()
       {
        new Inner().show();        

        }
}

内部类可以存放在局部位置上,内部类在局部位置上只能访问局部中被final修饰的局部变量(常量)

class Outer
{
    int num =3;
    void method(final int y )
    {
        final int x=0;//从内部类中访问局部变量x,需要被声明为最终类型
        class Inner
        {
            void show()
            {
            System.out.println("show..."+num);
            System.out.ptintln("show..."+x);//从内部类中访问局部变量x,需要被声明为最终类型
            System.out.println("show..."+y);//从内部类中访问局部变量x,需要被声明为最终类型
            }
        }
       Inner in =new Inner();
       in.show();
    }
    //不能在另外一个方法里面创建Inner对象,因为她不知道这个方法里面有inner
}

匿名内部类。就是内部类的简写格式。

必须由前提。

内部类必须继承或者实现一个外部类或者接口。

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

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

abstract class Demo
{
    abstract void show1();
    abstract void show2();
}
/*通常的使用场景之一:
当函数参数是接口类型时,而且接口中的方法不超过三个
可以用匿名内部类作为实际参数进行传递
*/
class Outer
{
    int num =4;
       
    public void method()
    {
        Demo in=new Demo()    //匿名内部类
            {
                void show()
                {
                    System.out.println("show1......"+num);
                   }
                void show2()
                  {
                     System.out.println("show2......"+num);
                    }
            };
            in.show1();
            in.show2();   


    }

}

匿名内部类的应用:

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

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

class Demo_Inner
{
    public static void main(String[] args)
    {
        System.out.println("Hello world!");
        show(new Inter()
        {
            public void show1();
            public void show2();
        });
    }
    public static void show(Inter in )
    {
        in.show1();
        in.show2();
    }
    

}

面试题,重要!

1、

class Outer
{
       void method()
        {
            new Object()
            {
                 public void show()
                   {
                        System.out.println("show run");                       

                        }   
             }.show(); //编译成功

        }

}

2、

class Outer
{
       void method()
        {
            Object obj = new Object()
            {
                 public void show()
                   {
                        System.out.println("show run");                       

                        }   
             };
                obj.show();//编译失败:因为匿名内部类这个子类对象被向上转型为Object类型
                                       //这样就不能再使用子类特头的方法了。
            

        }

}