java内部类

一、内部类的分类

  1. 成员内部类
  2. 静态内部类
  3. 局部内部类
  4. 匿名内部类

二、内部类的概念

  • 概念:在一个类的内部再定义一个完整的类

  • 特点:

    • 编译后可生成独立的字节码文件
    • 内部类可直接访问外部类的私有成员,而不破坏封装
    class Body{
        private String name="han";
        class Head{
            public  void show(){
                System.out.println(name);
            }
        }
    }
    
    • 可为外部类提供必要的内部功能组件,比如上面的身体和头的例子,头是身体的一部分

三、成员内部类

  • 在类的内部定义,与实例变量、实例方法同级别的类
  • 外部类的一个实例部分,创建内部类对象时,必须依赖外部类对象
public class InnerClass {
    public static void  main(String[] args) {
//        Body body = new Body();
//        Body.Head head = body.new Head();
//        head.show();
        //通过外部类调用内部类
        new Body().new Head().show();
    }
}
class Body{
    private String name="han";
     class Head{
        private int age=20;
        public  void show(){
            System.out.println(name);
            System.out.println(age);
        }
    }
}
  • 当外部类和内部类中存在重名属性时,会优先访问内部类属性,若想访问外部类的重名属性,需要用类名.this.属性
 public class InnerClass {
    public static void  main(String[] args) {
//        Body body = new Body();
//        Body.Head head = body.new Head();
//        head.show();
        //通过外部类调用内部类
        new Body().new Head().show();
    }
}
class Body{
    private String name="han";
     class Head{
        private int age=20;
        private String name="song";
        public  void show(){
            //若想访问外部类的重名属性,需要用类名.this.属性
            System.out.println(Body.this.name);
            System.out.println(name);
            System.out.println(age);
        }
    }
}
/*
* 输出:
* han
* song
* 20
* */
  • 成员内部类中不能定义静态成员,但可以定义静态常量
private static final String address="山东";

四、静态内部类

  • 不依赖外部类对象,可直接创建或通过类名访问,可声明静态成员
public class StaticClass {
    public static void main(String[] args) {
        Body2.Head head=new Body2.Head();
        head.show();
    }
}
class Body2{
    private String name="han";
    //静态内部类
    static class Head{
        private int age=20;
        private String name="song";
        //可定义静态成员
        private static String address="山东";
        public  void show(){
            //调用外部类成员
            Body2 body=new Body2();
            System.out.println(body.name);
            //调用内部成员
            System.out.println(name);
            System.out.println(age);
            //调用内部类静态成员
            System.out.println(Head.address);
        }
    }
}

五、局部内部类

  • 定义在外部类的方法中,作用范围和创建对象范围仅限于当前方法
  • 局部内部类访问外部类当前方法中的局部变量时,因无法保障变量的生命周期与自身相同,变量必须用final修饰
  • 限制类的使用范围,只能在当前方法中使用
public class JvBuClass {
    public static void main(String[] args) {
        Body3 body=new Body3();
        body.Test();
    }
}
//外部类
class Body3{
    private String name="han";
    private int age=20;
    public void Test(){
         String test="test";//jdk1.8final可省略
        //局部内部类就是和上面的test同一级别的成员
        class Head{
            private String name="song";
            private int age=21;
            //局部内部类中不能有静态成员,但可以有静态常量
            private final static String adress="山东";
            public void show(){
                //调用外部类成员
                System.out.println(Body3.this.name);
                System.out.println(Body3.this.age);
                //调用局部内部类成员
                System.out.println(this.name);
                System.out.println(this.age);
                //访问局部变量,jdk1.7要求必须是常量final来修饰,jdk1.8自动添加final
                System.out.println(test);
            }
        }
        //实例化局部内部类,并调用show方法
        Head head=new Head();
        head.show();
    }
}

六、匿名内部类

  • 没有类名的局部内部类(一切特征与局部内部类相同)
  • 必须继承一个父类或者实现一个接口
  • 相当于、实现类、创建对象的语法合并,只能创建一个该类的对象,可减少代码量,但可读性较差
  • 本质上匿名内部类是有名字的,编译后也会生成相应的字节码文件

//usb接口
public interface Usb {
    void Service();
}
//实现usb接口的鼠标类
public class Mouse implements Usb{
    @Override
    public void Service() {
        System.out.println("连接成功,鼠标开始运行");
    }
}
//程序入口 
public class Test {
    public static void main(String[] args) {
        //调用实现usb接口的鼠标实例
        Usb usb=new Mouse();
        usb.Service();
        //创建一个局部内部类,来创建一个风扇实例
        class Fan implements Usb{
            @Override
            public void Service() {
                System.out.println("风扇连接成功...");
            }
        }
        Usb usb1=new Fan();
        usb1.Service();
        //创建一个匿名内部类,来创建一个键盘实例
        Usb usb2=new Usb() {
            @Override
            public void Service() {
                System.out.println("键盘开始工作....");
            }
        };
        usb2.Service();
    }
}
posted @ 2022-01-12 18:52  是韩信啊  阅读(27)  评论(0编辑  收藏  举报