11.[Java 面向对象] 包与访问修饰符


1. 包

1.1 介绍包

  1. 包的本质就是创建不同的文件夹,来保存类文件
  2. 同一个包内不允许有重名的类,但是可以在不同包中相同名字的类
  3. 通过包可以进行访问权限的控制
  4. 当系统比较复杂时, 类会比较多, 使用包可以方便对类进行管理
  • 声明包的基本语法
// package 关键字, 表示打包,声明所属包
// com.hnbian 表示包名

package com.hnbian;

存储系统中包的组织形式

  • 代码示例(使用包分隔名称相同的类)
// 1. 创建 com.hnbian.part1.oop.package_.pkg01 包
// 2. 在包中创建 Dog 类
package com.hnbian.part1.oop.package_.pkg01;

public class Dog {
    public static void main(String args[]){

    }

    public void say(){
        System.out.println("com.hnbian.part1.oop.package_.pkg01 下的类");
    }
}

// 3. 创建 com.hnbian.part1.oop.package_.pkg02 包
// 4. 在包中创建 Dog 类
package com.hnbian.part1.oop.package_.pkg02;

public class Dog {
    public static void main(String args[]){

    }

    public void say(){
        System.out.println("com.hnbian.part1.oop.package_.pkg02 下的类");
    }
}

// 5. 在 com.hnbian.part1.oop.package_ 包 中创建 PackageTest 类 测试不同包中的同名类
package com.hnbian.part1.oop.package_;

public class PackageTest {
    public static void main(String[] args) {
        com.hnbian.part1.oop.package_.pkg01.Dog dog1 = 
                new com.hnbian.part1.oop.package_.pkg01.Dog();

        com.hnbian.part1.oop.package_.pkg02.Dog dog2 = 
                new com.hnbian.part1.oop.package_.pkg02.Dog();

        dog1.say();
        dog2.say();
    }
}

1.2 包的命名规则

  1. 包名只能包含数字, 字母, 下划线, 圆点

  2. 包名不能用数字开头

  3. 包名不能是关键字或保留字

  4. 包名通常使用小写字母 + 圆点

  5. 包名规范一般是 com.公司名.项目名.业务模块名 如:

// 用户模块
com.hnbian.crm.user 

1.3 常用的包

一个包下会有很多的类, Java 中常用的包有:

包名 说明
java.lang 基本包, 由 Java 默认引入, 不需要显式引入
java.util 系统提供的工具包, 如使用过的 scanner 就在此包中
java.net 网络包, 做网络开发会使用到此包下的一些类
java.awt 做 Java 界面开发会用到此包下的一些类

1.4 引入包

如果想要使用一个包下面的某个类, 那么必须先将该包下的引入,引入包时既可以引用包下的所有类,也可以指定引入某个类

如:

// 引入 util 包下的所有类
import java.util.*;

// 指定引入 util 包下的 Scanner 类
import java.util.Scanner; 
  • 代码示例
  • 使用系统 提供的Arrays 类完成对数组的排序
// 引入java.util包 的 Arrays 类
import java.util.Arrays;

// 包测试代码
public class PackageTest02 {
    public static void main(String[] args) {
        int[] arr= new int[]{3,5,7,8,4,2,1};
        // 使用引入的 Arrays 类 的 sort 方法对数组进行排序
        Arrays.sort(arr);

        for (int i = 0; i < arr.length; i++) {
            System.out.println(arr[i]);
        }
    }
}

1.5 其他

  • package 的作用是声明当前类所在的包, 需要放在类的最上面, 一个类中最多只有一句 package

  • import 用于引入包中包含的类

  • import 指令位置放在 package的下面,在类定义的上面, 可以有0到多条,并且没有顺序要求

// 声明包
// package 的作用是声明当前类所在的包, 需要放在类的最上面, 一个类中最多只能只有一个 package
package com.hnbian.process;

// 不建议使用 * 的方式引入包下的全部类
// 如:引入 util 包下的 Scanner 类
import java.util.Scanner;
// import 语句要求放置在 package 下面, 类定义的上面, 但且多条 import 语句之间没有顺序要求

public class Switch02 {
    public static void main(String[] args) {
        Scanner scanner  = new Scanner(System.in);
    }
}

2. 访问修饰符

2.1 介绍

访问修饰符用于控制方法和属性的访问权限

  • 修饰符可以用来修饰类中的属性, 成员方法以及类

  • 只有默认和 public 才能修饰类

  • 修饰符修饰成员方法和属性的访问规则一致

  • Java 中提供了四种访问控制修饰符,

  1. 公开级别: 用 public 修饰,对外公开

  2. 受保护级别: 用 protedted 修饰, 对子类和同一个包中的类公开

  3. 默认级别: 不使用访问修饰符,向同一个包中的类公开

  4. 私有级别: 用 private 修饰,不对外公开, 只能在类本身访问

详细如下表:

级别 访问修饰符 本类 同包 子类 不同包
公开 public ✔️ ✔️ ✔️ ✔️
受保护 protected ✔️ ✔️ ✔️
默认 - ✔️ ✔️
私有 Private ✔️

测试访问修饰符

  1. 测试在 同类 中访问不同的修饰符修饰的变量
不同访问级别的变量 【同类】Modifier01 访问 Modifier01
public ✔️
protected ✔️
- ✔️
Private ✔️
package com.hnbian.part1.oop.modifier;

public class Modifier01 {
    // 定义四种属性,分别使用四种不同的访问修饰符修饰
    public String public_ = "publicVariable";

    protected String protected_ = "protectedVariable";

    String default_ = "defaultVariable";

     private String private_ = "privateVariable";

     // 在本类中可以访问 所有的方法
     public void method(){
         System.out.println("public_ == "+ public_);
         System.out.println("protected_ == "+ protected_);
         System.out.println("default_ == "+ default_);
         System.out.println("private_ == "+ private_);
     }

    public static void main(String[] args) {
        Modifier01 modifier01 = new Modifier01();
        modifier01.method();
    }
}
  1. 测试在 同包 中访问不同的修饰符修饰的变量
不同访问级别的变量 【同包】Modifier02 访问 Modifier01
public ✔️
protected ✔️
- ✔️
Private X
package com.hnbian.part1.oop.modifier;

public class Modifier02 {
    public static void main(String[] args) {
        Modifier01 modifier01 = new Modifier01();
        // 在相同的包中可以访问 public、protected、default 修饰的变量
        System.out.println("public_ == "+ modifier01.public_);
        System.out.println("protected_ == "+ modifier01.protected_);
        System.out.println("default_ == "+ modifier01.default_);
        // 无法访问到 private 修饰的变量 private_'
        // 提示信息:has private access in 'com.hnbian.part1.oop.modifier.Modifier01'
        //System.out.println("private_ == "+ modifier01.private_);

        // 可以调用 Modifier01 中的类,间接的访问 private 修饰的变量
        System.out.println("=========================");
        modifier01.method();
    }
}
  1. 测试在 不同包 中访问不同的修饰符修饰的变量
【不同包】Modifier03 访问 Modifier01
public ✔️
protected X
- X
Private X
package com.hnbian.part1.oop.modifier.sub;

import com.hnbian.part1.oop.modifier.Modifier01;

public class Modifier03 {
    public static void main(String[] args) {
        Modifier01 modifier01 = new Modifier01();
        // 在相同的包中可以访问 public 修饰的变量
        System.out.println("public_ == "+ modifier01.public_);
        // 无法访问到 protected 修饰的变量
        // 提示信息:'protected_' has protected access in 'com.hnbian.part1.oop.modifier.Modifier01'
        // System.out.println("protected_ == "+ modifier01.protected_);

        // 无法访问到 默认权限 修饰的变量
        // 提示信息:'default_' is not public in 'com.hnbian.part1.oop.modifier.Modifier01'.
        // Cannot be accessed from outside package
        //System.out.println("default_ == "+ modifier01.default_);

        // 无法访问到 private 修饰的变量
        // 提示信息: 'private_' has private access in 'com.hnbian.part1.oop.modifier.Modifier01'
        //System.out.println("private_ == "+ modifier01.private_);

        // 可以调用 Modifier01 中的类,间接的访问 private 修饰的变量
        System.out.println("=========================");
        modifier01.method();
    }
}
  1. 测试在 同包子类 中访问不同的修饰符修饰的变量
【同包子类】Modifier01_sub对象访问 Modifier01 【同包子类】Modifier01对象 访问 Modifier01
public ✔️ ✔️
protected ✔️ ✔️
- ✔️ ✔️
Private X X
package com.hnbian.part1.oop.modifier;

public class Modifier01_sub extends Modifier01{
    public static void main(String[] args) {
        // 实例化 Modifier01 对象
        Modifier01 modifier01 = new Modifier01();
        // 使用 Modifier01 对象访问
        System.out.println("public_ == "+ modifier01.public_);
        System.out.println("protected_ == "+ modifier01.protected_);
        System.out.println("default_ == "+ modifier01.default_);
        // System.out.println("default_ == "+ modifier01.private_); // 无法访问

        // 实例化 Modifier01_sub 对象
        Modifier01_sub modifier01_sub = new Modifier01_sub();
        // 使用 Modifier01_sub 对象访问
        System.out.println("public_ == "+ modifier01_sub.public_);
        System.out.println("protected_ == "+ modifier01_sub.protected_);
        System.out.println("default_ == "+ modifier01_sub.default_);
        // System.out.println("default_ == "+ modifier01_sub.private_); // 无法访问

        // 可以调用 Modifier01 中的类,间接的访问 private 修饰的变量
        System.out.println("=========================");
        modifier01.method();
    }
}
  1. 测试在 不同包子类 中访问不同的修饰符修饰的变量
【不同包子类】Modifier01_sub对象访问 Modifier01 【不同包子类】Modifier01对象 访问 Modifier01
public ✔️ ✔️
protected ✔️ X
- X X
Private X X
package com.hnbian.part1.oop.modifier.sub;

import com.hnbian.part1.oop.modifier.Modifier01;

public class Modifier01_sub extends Modifier01{
    public static void main(String[] args) {

        // 实例化 Modifier01 对象
        Modifier01 modifier01 = new Modifier01();
        // 使用 Modifier01 对象访问
        // 在相同的包中可以访问 public、protected、default 修饰的变量
        System.out.println("public_ == "+ modifier01.public_);
        // System.out.println("protected_ == "+ modifier01.protected_); // 无法访问
        // System.out.println("default_ == "+ modifier01.default_); // 无法访问
        // System.out.println("default_ == "+ modifier01.private_); // 无法访问

        // 实例化 Modifier01_sub 对象
        Modifier01_sub modifier01_sub = new Modifier01_sub();
        // 使用 Modifier01_sub 对象访问
        System.out.println("public_ == "+ modifier01_sub.public_);
        System.out.println("protected_ == "+ modifier01_sub.protected_);
        // System.out.println("default_ == "+ modifier01_sub.default_); // 无法访问
        // System.out.println("default_ == "+ modifier01_sub.private_); // 无法访问

        // 可以调用 Modifier01 中的类,间接的访问 private 修饰的变量
        System.out.println("=========================");
        modifier01.method();
    }
}

文章作者: hnbian
版权声明: 本博客所有文章除特別声明外,均采用 CC BY 4.0 许可协议。转载请注明来源 hnbian !
评论
 上一篇
12.[Java 面向对象] 封装与继承 12.[Java 面向对象] 封装与继承
1. 封装1.1 封装介绍封装是面向对象编程的三个基本特征之一,其余两个特征是继承与多态。 封装(encapsulation) 就是将对象的 属性 或 方法 藏在对象的内部被保护起来 程序的其他部分只能通过被授权的方法才能对封装后的 属性
2018-02-01
下一篇 
10.[Java 面向对象] 对象的属性与方法 10.[Java 面向对象] 对象的属性与方法
1. 类与对象1.1 类和对象的区别和联系 类 是抽象的概念,是一个数据类型,代表一类事物,比如人类,鸟类等等… 对象 是具体的实际的,代表一个具体事物,即实例,比如 我的同学 “小明” 是人类的一个实例 类是对象的模板,对象是类的个
2018-01-28
  目录