JavaSE4️⃣OOP - 包 & 嵌套类

1、包

1.1、package

1.1.1、概念

(package)

提供多层命名空间,方便管理组织 Java 文件。

  1. 作用

    1. 防止不同 Java 文件之间产生命名冲突
    2. 访问控制
    3. 将功能相似或相关的文件组织在一起,方便使用
  2. 语法:使用 package 语句,放在源文件的首行。

    1. 适用于所有类型(类、接口、枚举、注释)。

    2. 单个源文件只能包含一个 package 语句。

      package 包层级1[.包层级2.包层级3...];
      

1.1.2、命名

要求

  1. 全部为小写字母

  2. 可以是多层次结构,使用 . 分割。

    package indi.jaywee;
    

规范:为避免冲突,需要确定唯一的包名。

  1. 不以 java 开头,避免冲突。

  2. 通常由倒置域名开头,根据功能命名子包。

    package com.baidu;
    package com.baidu.utils;
    

1.1.3、注意

  1. 默认包:若没有定义包,则会存放在默认包中。

  2. 层次关系

    1. 包没有父子关系,不同的包层次之间独立。

    2. 要求包层次与文件层次一致(源文件、字节码文件)。

      src
       ├─ indi
       │  └─ secret
       │    └─ Person.java
       └─ com
          └─ baidu
            └─ Person.java
      
      bin
       ├─ indi
       │  └─ secret
       │    └─ Person.class
       └─ com
          └─ baidu
            └─ Person.class
      

1.2、类名

1.2.1、分类

  1. 简单类名:定义的 class 名。
  2. 全限类名包名.简单类名
    1. JVM 使用全限类名。
    2. 类加载器+全限类名才能唯一确定一个类

1.2.2、类的查找过程

编译器针对类名的检索步骤。

  • 全限类名:直接根据类名查找。
  • 简单类名:按以下顺序
    1. 查找当前 package 中是否存在。
    2. 查找 import 导入的包中是否包含。
    3. 查找 java.lang 中是否包含。
    4. 均不存在,则编译报错

1.3、import

1.3.1、跨包使用类

一个类通常会使用其它类。

当使用其它包的类的时候,无法直接使用简单类名。

  1. 全限类名

    包名.类名 变量名 = new 包名.类名(参数);
    
  2. 导包 + 简单类名:使用 import 导入指定包层次下的类。

    1. 位置:package 之后,类定义之前。

    2. 通配符 *:表示包下的所有类,但不包括子包下的类。

      package 当前包名;
      
      import 包名.类名;	// 指定的类
      import 包名.*;	// 包下的所有类
      
      class 当前类名{}
      

单个源文件只能包含一个 package 语句,

但可包含多个 import 语句。

1.3.2、特殊导入

  1. 默认导入:Java 为每个源文件默认导入以下类。

    1. 当前包的其它类。
    2. java.lang.*
  2. 静态导入(Java 5):导入某个类的静态结构,引用静态结构无需指定类名。

    import static java.lang.System.*;
    

1.3.3、失效情况

场景:同一个源文件导入了多个同名的类,无法使用简单类名。

此时必须使用全限类名,否则编译不通过。

示例

  1. 程序中导入两个包,其中都有 Date 类。

    import java.util.*;
    import java.sql.*;
    
  2. 指定要使用的类。

    Date d = new Date();	// 编译不通过
    
    java.util.Date d1 = new java.uti.Date();	//ok
    java.sql.Date d2 = new java.sql.Date();	//ok
    

1.4、系统类库

常见的 Java 内置类库,位于 java. 下。

含义 举例
java.lang 核心类库 基本数据类型、基本数学函数、 字符串处理、异常处理、线程类
java.lang.reflect 反射对象
java.io 标准输入输出 基本输入/输出流、文件输入/输出、过滤输入/输出流
java.util 工具类 日期时间、集合框架
java.util.zip 文件压缩
java.awt GUI 相关 低级绘图操作、图形界面组件、布局管理,用户界面交互控制、事件响应
java.net 网络功能 Socket、ServerSocket

2、嵌套类

Nested Class(嵌套类)

在类中定义(使用)的类。

内部类
(Inner Class)
匿名类
(Anonymous Class)
静态内部类
(Static Inner Class)
含义 定义在另一个类的内部 无需明确定义,可直接实例化 使用 static 修饰的内部类
实例化方式 通过外部类实例 new 直接 new,实现抽象方法 直接 new
依附于外部类实例
可引用外部类实例
可访问外部类 private 结构 仅静态结构

2.1、内部类

2.1.1、定义

Inner Class:定义在另一个类(外部类)的内部。

  1. 定义

    class 外部类 {
        class 内部类 {
        }
    }
    
  2. 实例化:通过外部类实例的 new

    // 先外后内
    外部类 outer = new 外部类(参数);
    outer.new 内部类(参数);
    
    // 一步到位
    new 外部类(参数).new 内部类(参数);
    

2.1.2、特点

实例不能单独存在,依附于外部类的实例

体现为两个方面

  1. 实例引用:即可引用当前实例,也可引用外部类实例
    1. 内部类实例this.
    2. 外部类实例外部类名.this.
  2. 私有结构访问可访问外部类的 private 结构

字节码文件

  • 外部类:编译为 外部类名.class
  • 内部类:编译为 外部类名$内部类名.class

2.1.2、示例

  1. 定义外部类和内部类

    public class Outer {
        private String name;
    
        public Outer(String name) {
            this.name = name;
        }
    
        // 内部类
        class Inner {
            private int age;
            
            Inner(int age) {
                this.age = age;
            }
                
            void show() {
                System.out.println(Outer.this.name + this.age);
            }
        }
    }
    
  2. 实例化:先实例化 Outer,再通过 outer 实例化 Innter。

    public static void main(String[] args) {
        // 实例化外部类
        Outer outer = new Outer("Nested");
        // 实例化内部类
        Outer.Inner inner = outer.new Inner();
        inner.hello();
    }
    

2.2、匿名类

2.2.1、定义

Anonymous Class:无需明确定义一个 class,可直接实例化。

定义实例化):通过 new 直接创建

new 类型() {
    // 实现抽象方法
}

2.2.2、特点

类似 Inner Class(依附于外部类的实例

  1. 实例引用:可引用当前实例,也可以引用外部类实例。
  2. 私有结构访问:可访问外部类的 private 结构。

字节码文件

  • 外部类:编译为 外部类名.class
  • 匿名类:编译为 外部类名$1.class(若有多个匿名类,数字依次增加)

2.2.2、示例

Runnable 是一个接口,定义匿名类并使用。

  1. 定义匿名类,实现接口的抽象方法。

  2. 通过 new 实例化该匿名类。

  3. 转型为 Runnable 类型。

    class Outer {
        private String name;
    
        public void showName() {
            Runnable r = new Runnable() {
                @Override
                public void run() {
                    System.out.println(Outer.this.name);
                }
            };
            
            new Thread(r).start();
        }
    }
    

2.3、静态内部类

2.3.1、定义

Static Inner Class:使用 static 修饰。

  1. 定义

    class 外部类 {
        static class 匿名内部类 {
        }
    }
    
  2. 实例化:通过 new 直接创建

    new 外部类.内部类(参数);
    

2.1.2、特点

具有独立性,与外部类实例无关。

因此跟 Inner Class 的特点不同。

  1. 实例引用:可引用当前实例,无法引用外部类的实例
  2. 私有结构访问:仅可访问外部类的私有静态结构

2.3.2、示例

  1. 声明类

    public class StaticOuter {
        private static String name;
    
        // 静态内部类
        static class StaticInner {
            private int age;
    
            StaticInner(int age) {
                this.age = age;
            }
    
            void show() {
                // 访问外部类的静态属性
                System.out.println(name + this.age);
            }
        }
    }
    
  2. 使用

    new StaticOuter.StaticInner(18);
    
posted @ 2023-02-06 23:05  Jaywee  阅读(25)  评论(0编辑  收藏  举报

👇