简介:

        Java在类中定义的类就叫内部类,主要分为下面两种类型

1.成员内部类

public class Fish {
    private int age = 10086;
    private static int sex;
    
    //外部类普通方法
    private void talk() {
    }

	//外部类静态方法
    private static void run() {
    }

    //外部类如何调用内部类
    public void jump() {
        Fly fly = new Fly(); //外部类想要访问内部类,必须创建他的对象
        System.out.println(fly.age); //但可以访问他任意的变量和方法
        fly.method_4();
    }

	//定义局部内部类
    public Object getObj() {
        class Zsf { 
            //使用方法中局部变量与下面匿名内部类使用一样
            public void method_test() {
                System.out.println("Im method_test()");
            }
        }
        Zsf zsf = new Zsf();
        return zsf;
    }

    /**
     * 成员内部类1:
     * static修饰只能访问外部类静态的方法和变量
     */
    public static class Cat {
        public void method_1() {
            run();
            System.out.println(sex);
        }
    }

  	/**
     * 成员内部类2:
     * 能访问外部类中所有变量和方法
     */
    public class Bird {
        public void method_2() {
            run();
            talk();
            System.out.println(age);
            System.out.println(sex);
        }
    }

	/**
     * 成员内部类3:
     * 内部类中this与外部类中this如何调用
     */
    public class Fly {
        private int age = 10010;

        public void method_3() {
            //当与外部类有同名变量时,优先访问本类中的,如果没有才去外部类中找
            System.out.println(age); //age相当于this.age
            System.out.println(Fish.this.age); //访问外部类中变量,通过Fish.this引用
        }

        private void method_4() {
            System.out.println("this age is : " + this.age);
        }
    }
}

拓展内部接口:

        内部接口权限修饰符与内部类的权限修饰符差不多是一样的

public class Fish {
    private int age = 10086;
    private static int sex;
    //默认的修饰符表示只能在本包中被实现
    interface FistInterface{
        void show();
    }
    
    //默认修饰符表示只能在本类中被实现
    private interface TwoInterface{
        void run();
    }
    
    class Impl3 implements TwoInterface{
        @Override
        public void run() {
            
        }
    }
}

class Impl2 implements Fish.FistInterface{
    @Override
    public void show() {
        
    }
}

//=======================================
//ThreeInterface与FistInterface接口同包
public class ThreeInterface implements Fish.FistInterface {
    @Override
    public void show() {

    }
}

2.匿名内部类:

        实现匿名内部类需要继承类或实现一个接口

public interface ThreeInterface {
    void go();
}

//=====================================
public class Pig {
     public void about(){
        System.out.println("super.about()...");
    }
}

//=====================================
public class App {
    public static void main(String[] args) throws Exception {
        int age = 12;
        ThreeInterface threeInterface = new ThreeInterface() {
            @Override
            public void go() {
                //一旦匿名内部类中使用了方法中的变量,那么该变量就不能被修改了,只能被访问
                //我的理解是创建匿名内部类对象时,就已经确定好了age变量的值,后续再更改的话,就会出现不一致的情况,底层Jvm就不看了
                //既然不能更改,不如直接使用final修饰变量
                System.out.println(age);
            }
        };
        //age = 3; //不能被修改

        Pig pig = new Pig() {
            @Override
            public void about() {
                System.out.println("subclass.about()...");
            }

            public void show() {
                System.out.println("supclass.show()...");
            }
        };
        //为什么不能访问
        //注意:new Pig(){}这种写法相当于继承Pig类,是Pig的一个子类,只不过是匿名的,根据自动向上转型原则,转型后只能访问到父类中的方法
        //以前可以通过向下转型来访问子类,但这里子类是匿名的所有就无法通过转型来访问
        //pig.show();
        pig.about();

        //如何访问匿名内部类中定义的方法,下面是一种方式
        new Pig() {
            public void show() {
                System.out.println("supclass.show()...");
            }
        }.show();
    }
}