| 一、内部类的概念 
 内部类的是定义在另一个类中的类 一般分为: 本地内部类实例内部类静态内部类匿名内部类
 二、内部类的分类1.本地内部类 
 定义在方法当中的类。 public class TestDemo {
    public void func(){
        class  Test{
            public int a;
        }
        
    }
 本地内部类,我们用得比较少,我们写本地内部类的时候一定要谨慎。 同时,本地内部类有一个很大的缺点:只能在当前方法中使用。 2.实例内部类 
 实例内部类是指没有用 static 修饰的内部类,有的地方也称为非静态内部类。 简单示例如下: public class OuterClass {
    class InnerClass {
        
    }
}
 上面的InnerClass就是实力内部类了。 实例内部类的注意事项有以下几点,我们通过实例来一一了解: 在实例内部类中不能定义一个静态的成员变量,如果非要定义,只能定义一个静态常量,也就是用final修饰。
 class OuterClass{
    
    class InnerClass{
        public int data4=4;
        private int data5 = 5;
        
        
        public static final int data6 = 6;
        }
     }
 我们如何实例化 实例内部类的对象?
  
 外部类名.内部类名 变量 = 外部类对象的引用.new 内部类(); class OuterClass{
    
    class InnerClass{
        public int data4=4;
        private int data5 = 5;
        
        
        public static final int data6 = 6;
        }
     }
public static void main(String[] args) {
        OuterClass outerClass = new OuterClass();
        
        
        OuterClass.InnerClass innerClass =  outerClass.new InnerClass();
    }
 实例内部类当中,如果包含了和外部类同名的成员变量,我们如何在实例内部类中访问?
  
 我们可以通过外部类的this来访问。注意:我们实例内部类当中包含了两个this,一个是外部类的this,一个是内部类的this。 
class OuterClass{
    public int data1= 1;
    
    class InnerClass{
        public int data1=999;
        public InnerClass(){
            System.out.println("不带参数的内部类构造方法");
        }
        public void test(){
            System.out.println(OuterClass.this.data1);
            System.out.println(this.data1);
        }
    }
}
public class TestDemo {
    public static void main(String[] args) {
    
        OuterClass outerClass = new OuterClass();
        OuterClass.InnerClass innerClass =  outerClass.new InnerClass();
        innerClass.test();
    }
}
 
 3.静态内部类 
 实例内部类是指用 static 修饰的内部类 public class OuterClass {
    static class InnerClass {
        
    }
}
 静态内部类的一些问题: 如何访问外部类的普通成员变量?
 静态内部类不能访问外部类的实例成员,只能访问外部类的类成员。  class OuterClass2{
    public int data1 = 1;
    private int data2 = 2;
    public static int data3 = 3;
    
    static class InnerClass{
        public int data4 = 4;
        private int data5 = 5;
        public static int data6 = 6;
        
        public OuterClass2 out;
        public InnerClass(OuterClass2 out){
            this.out = out;
        }
        public void test(){
            
            System.out.println(out.data1);
            
            
            System.out.println(data3);
            System.out.println(data4);
            System.out.println(data5);
            System.out.println(data6);
            System.out.println("InnerClass::test()");
        }
    }
 如何实例化静态成员变量?
  
 外部类名.内部类名 变量 =new 外部类对象的引用.内部类(变量); public static void main(String[] args) {
        OuterClass2 outerClass2 = new OuterClass2();
        OuterClass2.InnerClass innerClass = new OuterClass2.InnerClass(outerClass2);
        innerClass.test();
    }
 打印结果: 
 3.匿名内部类 
 名内部类就是一个没有显式的名字的内部类。匿名内部类没有类名,因此就不可能有构造函数,不能创建对象。
 语法一: new 实现接口()
{
    
}
 语法二: new 父类构造器(实参列表)
{
  
}
 实例: class Test{
    public void test(){
        System.out.println("test()haha!");
    }
}
public class TestDemo2 {
    public static void main(String[] args) {
        new Test(){
            @Override
            public void test(){
                System.out.println("我是重写的test方法");
            }
        }.test();
    }
 就是定义了一个类Test,在类里定义了一个test方法。调用他的实例方法test()。 然后调用它的test()方法。 在调用test()方法的同时,重写了test()方法,所以打印结果为:我是重写的test方法。 输出结果:
  所以,匿名内部类的最大好处就是可以简化我们代码的书写。
 
 总结为什么需要使用内部类呢? 其主要原因有以下三点:?内部类方法可以访问该类定义所在的作用域中的数据, 包括私有的数据。
 ?内部类可以对同一个包中的其他类隐藏起来。 ?当想要定义一个回调函数且不想编写大量代码时,使用匿名 (anonymous) 内部类比较便捷。 |