内部类

4种内部类

1. 局部内部类

1. 匿名内部类

1. 成员内部类

1. 静态内部类 (成员内部类,静态内部类是放在外部类的成员位置上,本质是一个成员)

静态方法只能访问静态成员,非静态方法可以访问静态和非静态成员

静态方法和类一起加载,非静态方法只有在创建对象时才会加载。所以才有了静态方法不能直接调用非静态(因为静态方法加载时类还没有初始化也就还没有非静态方法),非静态方法可以直接调用静态方法(因为非静态方法加载时静态方法早就加载了)

一.局部内部类

局部内部类
public class JuBuOut {
    private int a = 1001;

    public static void main(String[] args) {
        JuBuOut outBody = new JuBuOut();//创建外部类的对象,用对象调用外部类方法
        outBody.out01();//方法执行,创建内部类,之后创建内部类对象,对局部方法进行调用
    }

    void out() {
        System.out.println("局部内部类可以直接调用外部方法,比如调用我");
    }

    void out01() {
        System.out.println("我是外部方法,我要在此创建一个局部内部类,");

        final class in01 {  //1.局部内部类(本质还是一个类)   2.不可以加访问修饰符public等,但可以加final(final 不能被继承)
            //3.局部内部类的作用域只在定义我的方法中或者代码块中
            private int a = 100;

            void in001() {
                System.out.println("我就是局内内部类中的方法,我要开始访问我的局部变量和外部变量");
                System.out.println(a);//局部内部类自己的局部变量
                System.out.println(JuBuOut.this.a);//4.用类名加.this+变量名就可以访问到外部成员变量
                                 //JuBuOut.this的本质就是外部类的对象,谁调用了out01,JuBuOut.this就是哪个对象

                out();  //5.局部内部类可以直接调用外部方法
            }
        }
        in01 inBody = new in01();//6.外部类在方法中直接创建内部类(in01)对象,然后调用in001方法
        inBody.in001();
    }
}

二.匿名内部类

匿名内部类的基本语法
new 类或接口(参数列表){ 类体 }; //不要忘记有分号( ; )

匿名内部类的两种使用方式

点击查看代码
public class NeiBuLeiTest {
    public static void main(String[] args) {
        NeiBuLeiTest a = new NeiBuLeiTest();
        a.method();
    }

    public void method() {
        //第一种匿名内部类创建方法
        Person p1 = new Person() {
            @Override
            void speak() {
                System.out.println("匿名内部类重写了speak(方法)");
            }
        };
        p1.speak();//第一种调用方法

        //第二种匿名内部类创建方法
        new Person() {
            @Override
            void city(String name) {
                super.city(name);
            }
        }.city("China");//第一种调用方法
    }
}

class Person {
    void speak() {
        System.out.println("喜欢说话");
    }

    void city(String name) {
        System.out.println("匿名内部类调用方法传来的参数:" + name);
    }
}

可折叠代码的运行图

public class NiMingClass {     //外部其他类
    public static void main(String[] args) {
        WaiBu waibu1 = new WaiBu();
        waibu1.method();
    }
}

class WaiBu {   //外部类
    private int n = 10;//属性
    //它的本质是类(内部类),该类没有名字,同时还是一个对象;
    //匿名内部类是定义在外部类的局部位置(比如方法中) 并且没有类名

    public void method() { //方法
        //1.基于接口的匿名内部类  (传统方法是写一个类,实现该接口,并创建对象)
        //2.若实现该接口的类只使用一次,后面不再使用,可以使用匿名内部类来简化开发
        JieKou eg = new JieKou() {  //3.eg的编译类型是JieKou
            @Override
            public void cry() {
                System.out.println("匿名内部类好令人难过啊");
            }
        };
        System.out.println("eg的运行类型" + eg.getClass());//4.eg的运行类型(匿名内部类)是WaiBu$1
        eg.cry();//5.jdk底层在创建匿名内部类  WaiBu$1,立马创建了一个WaiBu$1的实例,并且把地址返回给 eg
        //6.匿名内部类使用一次,就不能再使用(不能再创建 new WaiBu$1(); ),但是 eg可以反复调用cry();方法

        //基于类的匿名内部类
        Father father = new Father("老张") {//这里的("老张")参数列表会传给Father类的构造器
            @Override
            public void test() {
                System.out.println("我在这重写了test()方法");
            }
        };
        System.out.println("father的运行类型" + father.getClass());
        father.test();
    }
}

interface JieKou {  //接口
    public void cry();
}

class Father {
    public Father(String name) {  //构造器
        System.out.println("传过来的name:" + name);
    }

    public void test() {  //方法
    }
}

三.成员内部类

public class ChengYuan {
    public static void main(String[] args) {
        Out01 out01 = new Out01();
        out01.run01();

        //外部其他类,使用成员内部类的两种方式
        //第一种方式
        //out01.new In01();相当于new In01()是out01对象的一个成员(一种语法)
        Out01.In01 in02 = out01.new In01();
        in02.test();

        //第二种方式 在外部类中,编写一个方法,可以返回In03的对象实例
        Out01.In01 in03 = out01.getIn03Instance();
        in03.test();
    }
}

class Out01 {  //外部类  
    private int a = 53;
    String name = "啊哈";

    void test02() {
        System.out.println(" 成员内部类可以直接调用test02()方法 ");
    }

    public class In01 {//1.成员内部类(定义在外部类的成员位置上),可以访问外部类的所有成员,包括私有的
        //(作用域和外部类其他成员一样,为整个类体)
        //2.可以添加任意访问修饰符public.private.默认.protected,因为它的地位就是一个成员
        void test() {
            System.out.println(" 访问外部类的成员变量 " + a + "和" + name);
            test02();//成员内部类可以直接调用test02()方法
            System.out.println("++++++++++++++++");
        }
    }

    public In01 getIn03Instance() {  //第二种 外部其他类,使用成员内部类创建方式的方法
        return new In01();      //方法返回一个In03的实例
    }

    void run01() { //创建一个成员内部类对象
        In01 in01 = new In01();
        in01.test();//调用成员内部类的方法
    }
}

四.静态内部类

public class StaticInClass {    //外部其他类
    public static void main(String[] args) {
        Outout out1 = new Outout();
        System.out.println("第一次");
        out1.eatTest();

        //外部其他类 访问 静态内部类
        //方式一    静态内部类可以通过类名直接访问(前提是满足访问权限,不可以是private)
        Outout.InIn in1 = new Outout.InIn();
        System.out.println("第二次");
        in1.eat();//调用静态内部类的方法

        //方式二,编写一个方法,可以返回in02的对象实例
        Outout.InIn in02 = out1.getin02();
        System.out.println("第三次");
        in02.eat();

        //由外部类直接调用静态方法,返回in03的对象实例
        Outout.InIn in03 = Outout.getin03();
        System.out.println("第四次");
        in03.eat();
    }
}

class Outout { //外部类
    private static String aa = "外部类";

    static void kfc() {
        System.out.println("静态内部类调用了我, 快v我50");
    }

    public static class InIn {//1.静态内部类  (作用域和外部类其他成员一样,为整个类体)
        //2.可以添加任意访问修饰符public.private.默认.protected,因为它的地位就是一个成员
        private static String aa = "静态内部类";

        public void eat() { //可以访问外部类的所有静态成员,包括私有的,但不能直接访问非静态成员
            System.out.println("访问外部类的成员变量aa:" + Outout.aa + "   静态内部类的aa:" + aa);
                         //如果外部类和静态内部类的成员重名时,默认遵循就近原则,
                        // 如果想访问外部类的重名成员时,则可以使用(外部类类名.成员变量名)
            kfc();
        }
    }

    public InIn getin02() {
        return new InIn();//返回一个InIn类的实例in02
    }

    public static InIn getin03() { //也可以用静态方法,然后有外部类直接调用此方法
        return new InIn();
    }

    void eatTest() {
        InIn inin1 = new InIn();
        inin1.eat();
    }
}

posted @ 2022-11-13 16:10  微风抚秀发  阅读(24)  评论(0)    收藏  举报