美文网首页Android基础Java 基础
Java 常用类 01. Java 内部类

Java 常用类 01. Java 内部类

作者: yjtuuige | 来源:发表于2021-12-14 20:50 被阅读0次

    1. 概念:

    • 在一个 类的内部 再定义一个完整的类。

    2. 分类:

    • 成员内部类
    • 静态内部类
    • 局部内部类
    • 匿名内部类

    3. 特点:

    1. 编译之后,可生成独立的字节码文件。
    2. 内部类可以直接访问外部类的私有成员,而不破坏封装。
    3. 可为外部类,提供必要的内部功能组件
    • 实例:
    package com.base.demo01;
    
    public class Outer {
        private String name;
        // 内部类Inner
        class Inner {
    
            public void print() {
                System.out.println(name);   // 直接调用外部类的私有成员
            }
        }
    }
    
    • 编译后:
    1. 成员内部类
    • 在类的内部定义,与实例变量、实例方法同级别的类。
    • 外部类的一个实例部分,创建内部类对象时,必须依赖外部类对象。
    • 当外部类、内部类存在重名属性时,会优先访问内部类属性。
      如要访问外部类属性时,需要用 外部类名.this :Outer.this.name
    • 成员内部类 不能定义静态成员,但可以定义静态常量( final )
    • 创建对象:(思路是一样的,只是后者看起来更简洁)
    // 调用方式 1:
    Outer outer = new Outer();//先创建外部类对象
    Inner inner = outer.new Inner();//通过外部类对象建立内部类对象
    // 调用方式 2:
    Outer.Inner inner = new Outer.new Inner();
    
    • 实例:
    package com.base.demo01;
    
    public class Demo01 {
        public static void main(String[] args) {
            //创建外部类对象
            Outer outer = new Outer();
            //创建内部类对象
            Outer.Inner inner = outer.new Inner();
            // 设置外部类属性值
            outer.setName("外部 name");
            outer.setAge(20);
            // 设置内部类属性值
            inner.setName("内部 name");
            inner.setQq("5435432");
            inner.setTel("010");
            // 调用内部类的方法
            inner.show();
        }
    }
    
    class Outer { // 外部类
        private String name;
        private int age;
    
        class Inner {  // 内部类
            //private static String sex; // 成员内部类中不能定义静态成员
            private String name;    // 与外部类重名的属性
            private String qq;
            private String tel;
    
            public void show() {
                // 调用外部类中的成员变量
                System.out.println("调用外部类成员结果:");
                // 重名时,调用外部类属性 (外部类名.this)
                System.out.println(Outer.this.name + " " + age);
                // 调用内部类中的成员变量
                System.out.println("调用内部类成员结果:");
                System.out.println(this.name);  // this.name 代表当前的内部类
                System.out.println(qq + " " + tel);
                System.out.println("重名优先调用:");
                System.out.println(name);   // 重名时,会优先访问内部类属性
            }
    
            public void setName(String name) {
                this.name = name;
            }
    
            public void setQq(String qq) {
                this.qq = qq;
            }
    
            public void setTel(String tel) {
                this.tel = tel;
            }
        }
    
        public void setName(String name) {
            this.name = name;
        }
    
        public void setAge(int age) {
            this.age = age;
        }
    }
    
    • 运行结果:
    1. 静态内部类
    • 不依赖外部类对象(相当于外部类),可直接创建或通过类名访问,可声明静态成员。
    • 只能直接访问外部类的静态成员(实例成员需实例化外部类对象)
    • 调用外部类属性:通过创建外部类对象调用
    // 1. 先创建外部类对象
    Outer outer = new Outer();
    // 2. 调用外部类对象的属性
    System.out.println(outer.name);
    
    • 调用静态内部类的静态属性:直接创建静态内部类对象
      Inner.count 通过静态内部类名,直接调用静态内部类的静态属性
    • 实例:
    package com.base.demo02;
    
    public class Outer {
        private String name = "Liu";
    
        static class Inner {
            private String tel;
            private static int count;
    
            public Inner(String tel, int count) {
                this.tel = tel;
                // Inner.count 通过静态内部类名,直接调用静态内部类的静态属性
                Inner.count = count;
            }
    
            public Inner() {
                this("",0);
            }
    
            public void print() {
                // 调用外部类属性
                // 1. 先创建外部类对象
                Outer outer = new Outer();
                // 2. 调用外部类对象的属性
                System.out.println(outer.name);
                // 调用内部类成员
                System.out.println(tel);
                // 调用静态内部类的静态属性
                System.out.println(count);
            }
        }
    }
    
    • 测试类
    package com.base.demo02;
    
    public class Test {
        public static void main(String[] args) {
            // 直接创建静态内部类对象
            Outer.Inner inner = new Outer.Inner("010", 1000);
            inner.print();
        }
    }
    
    • 运行结果:
    1. 局部内部类(方法中定义内部类)
    • 定义在 外部类方法 中,作用范围和创建对象范围仅限于当前方法。不能加任何访问修饰符
    • 局部内部类访问外部类当前方法中的局部变量时,因无法保障变量的生命周期与自身相同,变量必须修饰为 final
    • 限制类的使用范围。
    • 实例:
    package com.base.demo02;
    
    // 外部类
    public class OuterDemo01 {
        // 实例变量
        private String name = "Liu";
        private int age = 30;
    
        // 方法
        public void show() {
            // 定义局部变量
            String address = "北京";  // 默认final 内部类引用
    
            // 局部内部类:注意不能加任何访问修饰符
            class Inner {
                private String phone = "010";
                private String email = "Liu@qq.com";
    
                public void show2() {
                    // 访问外部类的属性
                    System.out.println(name); // 相当于 Outer.this.name
                    System.out.println(age);
                    // 访问内部类的属性
                    System.out.println(this.phone);  // 内部类属性
                    System.out.println(this.email);
    
                    // 访问局部变量 jdk1.7 要求必须常量 final,jdk1.8 自动添加 final
                    // 从内部类引用的本地变量必须是最终变量或实际上的最终变量
                    System.out.println(address);
                }
            }
            // 创建局部内部类对象
            Inner inner = new Inner();
            inner.show2();
        }
    }
    
    • 测试类
    package com.base;
    
    import com.base.demo02.OuterDemo01;
    
    public class Application {
        public static void main(String[] args) {
            OuterDemo01 outer = new OuterDemo01();
            outer.show();
        }
    }
    
    • 运行结果:
    1. 匿名内部类
    • 没有类名的局部内部类(一切特征都与局部内部类相同)。
    • 必须 继承一个父类 或者 实现一个接口
    • 定义类、实现类、创建对象的语法合并,只能创建一个该类的对象
    • 优点:减少代码量
    • 缺点:可读性较差
    • 实例:创建接口类
    package com.base.demo02;
    
    // 接口
    public interface Usb {
        void service();
    }
    
    • 创建类,实现接口
    package com.base.demo02;
    
    public class Mouse implements Usb {
        @Override
        public void service() {
            System.out.println("连接电脑成功,鼠标开始工作...");
        }
    }
    
    • 测试类
    package com.base;
    
    import com.base.demo02.Mouse;
    import com.base.demo02.Usb;
    
    public class Application {
        public static void main(String[] args) {
            // 第一种方式:创建接口类的变量
            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("匿名内部类  连接电脑成功,风扇开始工作...");
               }
            };
            */
            Usb usb2 = () -> System.out.println("匿名内部类  连接电脑成功,风扇开始工作...");
            usb2.service();
        }
    }
    
    • 运行结果:

    总结:

    • 从上面的案例可以发现:
      1. 使用内部类的最大好处,在于可以更方便地访问外部类中的私有属性。(优点)
      2. 使用内部类后代码比之前的更加复杂了,内部类的存在实际上已经破坏了一个类的基本结构。(缺点)

    相关文章

      网友评论

        本文标题:Java 常用类 01. Java 内部类

        本文链接:https://www.haomeiwen.com/subject/jkiefrtx.html