17.内部类

    将一个类定义在另一个类的里面,对里面那个类就称为内部类(内置类,嵌套类)。

    访问特点:

        内部类可以直接访问外部类中的成员,包括私有成员。

        而外部类要访问内部类中的成员必须要建立内部类的对象。

18.内部类的位置

    1.内部类定义在成员位置上

        可以被private static成员修饰符修饰。

        被static修饰的内部类只能访问外部类中的静态成员。

   

     2.内部类定义在局部位置上

        也可以直接访问外部类中的成员。

        同时可以访问所在局部中的局部变量,但必须是被final修饰的。

19.匿名内部类

        就是内部类的简化写法。

    前提:

        内部类可以继承或实现一个外部类或者接口。

    格式为:

        new 外部类名或者接口名(){覆盖类或者接口中的代码,(也可以自定义内容。)}

    简单理解:

        就是建立一个带内容的外部类或者接口的子类匿名对象。

class Outer{    private int num = 3;    static int num2 = 7;         //内部类:定义在成员位置上,它就相当于外部类的成员一样,可以被成员修饰符所修饰。    public class Inner{        void show(){        System.out.println("show num="+num);        }    }         void method(){        //外部类要访问内部类中的成员,必须要创建内部类中的对象        Inner in = new Inner();        in.show();    }              static class Inner2{//被static修饰的内部类只能访问外部类中的静态成员        void show2(){        System.out.println("show2 num2="+num2);        }    }         static class Inner3 {        //当内部类中定义了静态成员,该内部类必须被静态修饰        static void show3(){        System.out.println("show3 num2="+num2);        }    } }  class  InnerDemo{    public static void main(String[] args) {        /*        直接访问内部类成员的方式。        */        //1,对非静态的内部类中的非静态成员访问。        Outer.Inner in = new Outer().new Inner();        in.show();                 //2,访问静态内部类中的非静态成员。        Outer.Inner2 in = new Outer.Inner2();        in.show2();                 //3,访问静态内部类中的静态成员。        Outer.Inner3.show3();                     //外部类访问外部类的方法,该方法中有内部类对象访问的方法        Outer out = new Outer();        out.method();    }}

内部类直接访问外部类成员的原因

非静态的内部类之所以能直接访问外部类成员的原因是:它持有了一个外部类对象的引用。

class Outer{    private int num = 2;    class Inner{        private int num = 3;        void show(){            int num = 4;            System.out.println("num="+num);  //结果是4            System.out.println("num="+this.num);  //结果是3            System.out.println("num="+Outer.this.num);  //结果是2        }    }       void method(){        new Inner().show();    }}

内部类在局部访问的原因

class Outer{    private int num = 3;    void method(){        final int x = 7;   //内部类定义在局部中,只能访问被final修饰的局部变量。        //不被final修饰的局部变量生命周期随着方法的释放而释放。         class Inner{//定义在局部的内部类。             void show(){                System.out.println("x="+x);                //System.out.println("num="+num);            }    }        new Inner().show();    }} class Outer2{    private int num = 4;    Object obj ;     public void method(){        final int x = 4;        class Inner{            public String toString(){                return "hahah"+x;            }        }        this.obj = new Inner();    }}
class InnerDemo3 {    public static void main(String[] args) {        //new Outer().method();        Outer2 out = new Outer2();        out.method();        System.out.println(out.obj.toString());    }}
/*匿名内部类的形式。其实就是对内部类进行简化书写。必须有前提:内部类必须继承或者实现类或接口。 格式:new 父类名或者接口名(){定义内部类的内容;} 匿名内部类其实就是一个子类匿名对象。 */ abstract class AbsDemo{    abstract void function();} class Outer{    int num = 4;    /*    class Inner extends AbsDemo{        void function(){        System.out.println("num="+num);        }             }    */    void method(){        //new Inner().function();        new AbsDemo() {  //创建了子类的对象并且调用了子类的方法。                       //对内部类的描述。            void function(){            System.out.println("num===="+num);            }        }.function();  //枚红色的部分是绿色部分的简写, new X(){}是创建X子类对象    }} class NoNameInnerDemo {public static void main(String[] args) {    Outer out = new Outer();    out.method();    }}