美文网首页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 内部类

    1. 概念: 在一个 类的内部 再定义一个完整的类。 2. 分类: 成员内部类 静态内部类 局部内部类 匿名内部类...

  • PHP转JAVA的记录

    Java 数组 内部类 内部类的创建:内部类可以对包内其他类隐藏想实现一个接口时, 不想新建类文件 内部类可以访问...

  • Java编程基础(11)

    Java编程基础知识:Java内置包装内 1.Java Object类详解:Object类的常用方法(equals...

  • Kotlin内联类、内部类、嵌套类

    Kotlin内联类、内部类、嵌套类 在开始介绍Kotlin内联类、内部类、嵌套类之前,先简要回顾一下java中的内...

  • 2021-12-06、12-07

    今天简单的复习下Java内部类,面试有的时候问到。 Java内部类 什么是内部类? 内部类就是定义类里面的类。在J...

  • Java内部类

    Java内部类,简单来说就是将一个类定义在另一个类或者方法里面,主要分为成员内部类,局部内部类,匿名内部类和静态内...

  • JavaSE基础知识学习-----内部类

    内部类 类的五个成分:属性,方法,构造器,代码块,内部类。什么是内部类?在java中,允许一个类定义在另一个类的内...

  • scala中的内部类

    scala的内部类与java的内部类有些不同,Java中的内部类是包含了它的类的成员,Scala中,内部类的作用域...

  • Java 内部类详解

    标签(空格分隔): java 成员内部类 在java中允许一个类的内部定义另一个类,称为内部类(inner cla...

  • Java自学-接口与继承 内部类

    Java 内部类 内部类分为四种: 非静态内部类静态内部类匿名类本地类 步骤 1 : 非静态内部类 非静态内部类 ...

网友评论

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

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