探索 Java 权限修饰符的奥秘

news2025/1/2 22:59:48

目录

一、Java 权限修饰符初窥

(一)为啥要有权限修饰符

(二)Java 中的四种权限修饰符

二、private 权限修饰符 —— 私有领域的守护者

(一)private 的访问规则

(二)代码示例

三、default 权限修饰符 —— 默认的默契

(一)default 的访问规则

(二)代码示例

四、protected 权限修饰符 —— 继承中的特权

(一)protected 的访问规则

(二)代码示例

五、public 权限修饰符 —— 开放的大门

(一)public 的访问规则

(二)代码示例

六、权限修饰符的综合运用与最佳实践

(一)数据封装与权限修饰符

(二)继承与权限修饰符的搭配

(三)包的设计与权限修饰符的考虑


宝子们,今天咱们来深入聊聊 Java 中那些看似不起眼,但实则至关重要的权限修饰符。它们就像是一道道关卡,控制着代码的访问范围,决定了哪些部分可以被其他类看到和使用,哪些部分应该隐藏起来。理解好权限修饰符,能让我们写出更安全、更健壮、更易于维护的 Java 代码。

一、Java 权限修饰符初窥

(一)为啥要有权限修饰符

想象一下,你有一个装满宝贝的房间(一个 Java 类),有些宝贝是你愿意和朋友分享的(可以被其他类访问的成员),有些则是非常私人的,只想自己知道(只能在本类中访问的成员)。权限修饰符就像是房间的门锁和窗户的窗帘,帮助你控制谁能看到和触碰这些宝贝。

在一个大型的 Java 项目中,可能有很多不同的类相互协作。如果没有权限修饰符,任何一个类都可以随意访问和修改其他类的成员变量和方法,这将会导致代码的混乱和难以维护。例如,一个表示用户信息的类,其中的密码字段肯定不能被其他随便的类访问和修改,否则用户的信息安全就无法保障了。

(二)Java 中的四种权限修饰符

Java 主要有四种权限修饰符:privatedefault(默认,什么都不写)、protected 和 public。它们从最严格的访问限制到最宽松的访问限制依次排列,每个修饰符都有其特定的适用场景和作用。

二、private 权限修饰符 —— 私有领域的守护者

(一)private 的访问规则

当一个类的成员(变量或方法)被 private 修饰时,它就像是被锁在了一个只有自己能进入的小房间里,只有在这个类的内部才能访问它。其他任何类,无论是同一个包中的类还是不同包中的类,都无法直接访问 private 成员。

(二)代码示例

class BankAccount {
    // 账户余额,使用 private 修饰,确保只有本类可以访问和修改
    private double balance;

    public BankAccount(double initialBalance) {
        this.balance = initialBalance;
    }

    // 存款方法,在本类中操作 balance
    public void deposit(double amount) {
        if (amount > 0) {
            balance += amount;
            System.out.println("成功存入 " + amount + ",当前余额为 " + balance);
        } else {
            System.out.println("存款金额必须大于 0");
        }
    }

    // 取款方法,同样在本类中操作 balance
    public void withdraw(double amount) {
        if (amount > 0 && amount <= balance) {
            balance -= amount;
            System.out.println("成功取出 " + amount + ",当前余额为 " + balance);
        } else {
            System.out.println("余额不足或取款金额不正确");
        }
    }
}

public class PrivateExample {
    public static void main(String[] args) {
        BankAccount myAccount = new BankAccount(1000);
        myAccount.deposit(500);
        // 以下代码会报错,因为无法在 BankAccount 类外部直接访问 private 变量 balance
        // System.out.println(myAccount.balance);
        myAccount.withdraw(300);
    }
}

在这个例子中,balance 被 private 修饰,所以在 main 方法中无法直接访问它,只能通过 deposit 和 withdraw 方法来间接操作账户余额,这样就保证了余额数据的安全性和完整性,防止了外部的非法访问和修改。

三、default 权限修饰符 —— 默认的默契

(一)default 的访问规则

如果一个类的成员没有使用任何权限修饰符,那么它就具有默认的访问权限(也称为包访问权限)。这意味着这个成员可以被同一个包中的其他类访问,但对于不同包中的类来说,它是不可见的。这种默认的访问权限就像是在一个小圈子里(同一个包)大家默认可以互相分享一些信息,但对于圈子外的人(其他包中的类)则保持神秘。

(二)代码示例

首先创建一个名为 finance 的包,在其中定义两个类:

package finance;

class Budget {
    // 预算金额,使用默认访问权限
    double budgetAmount;

    public Budget(double amount) {
        this.budgetAmount = amount;
    }

    // 计算剩余预算的方法,可供同包中的类使用
    double calculateRemainingBudget(double expense) {
        return budgetAmount - expense;
    }
}

class ExpenseTracker {
    public static void main(String[] args) {
        Budget monthlyBudget = new Budget(5000);
        // 在同包的 ExpenseTracker 类中可以直接访问 Budget 类的 budgetAmount 变量和 calculateRemainingBudget 方法
        double remainingBudget = monthlyBudget.calculateRemainingBudget(2000);
        System.out.println("本月剩余预算:" + remainingBudget);
    }
}

然后在另一个包 outsideFinance 中尝试访问 Budget 类的成员:

package outsideFinance;

import finance.Budget;

public class OutsideAccess {
    public static void main(String[] args) {
        Budget anotherBudget = new Budget(3000);
        // 以下代码会报错,因为在不同包中无法访问 Budget 类的默认权限成员 budgetAmount 和 calculateRemainingBudget 方法
        // double remaining = anotherBudget.calculateRemainingBudget(1000);
        // System.out.println(anotherBudget.budgetAmount);
    }
}

从这个例子可以看出,Budget 类中的 budgetAmount 和 calculateRemainingBudget 方法在 finance 包内可以正常访问和使用,但在 outsideFinance 包中就无法直接访问,这就是 default 权限修饰符的作用。

四、protected 权限修饰符 —— 继承中的特权

(一)protected 的访问规则

protected 修饰符提供了一种在继承关系中更灵活的访问控制。被 protected 修饰的成员可以被同一个包中的其他类访问,就像 default 权限一样。但除此之外,它还可以被不同包中的子类访问和继承。这就像是给家族中的后代(子类)开了一扇特殊的门,让他们能够继承和访问一些祖先(父类)的特定遗产(成员),而对于家族外的人(其他包中的非子类),这些遗产仍然是隐藏的。

(二)代码示例

在 parent 包中定义一个父类:

package parent;

public class Animal {
    // 动物的名字,使用 protected 修饰,以便子类可以访问
    protected String name;

    public Animal(String name) {
        this.name = name;
    }

    // 动物发出声音的方法,使用 protected 修饰,子类可以重写
    protected void makeSound() {
        System.out.println("动物发出声音");
    }
}

在 child 包中定义一个子类继承自 Animal

package child;

import parent.Animal;

public class Dog extends Animal {
    public Dog(String name) {
        super(name);
    }

    // 重写父类的 makeSound 方法
    @Override
    protected void makeSound() {
        System.out.println(name + " 汪汪叫");
    }

    public void showName() {
        // 在子类中可以访问父类的 protected 成员 name
        System.out.println("这只狗的名字是:" + name);
    }
}

然后在 main 方法中测试:

package child;

public class Main {
    public static void main(String[] args) {
        Dog myDog = new Dog("旺财");
        myDog.showName();
        myDog.makeSound();
    }
}

在这个例子中,Animal 类中的 name 和 makeSound 方法被 protected 修饰,Dog 子类可以在不同包中访问和重写这些成员,体现了 protected 修饰符在继承关系中的特殊作用,既保证了一定的封装性,又允许子类进行扩展和定制。

五、public 权限修饰符 —— 开放的大门

(一)public 的访问规则

public 是最宽松的权限修饰符,被 public 修饰的类、成员变量和方法可以被任何其他类访问,无论它们是否在同一个包中。这就像是把东西放在了一个公共的广场上,所有人都可以看到和使用。一般来说,我们会将类的公共接口(其他类需要调用的方法和访问的变量)设置为 public,以便其他类能够方便地与这个类进行交互和协作。

(二)代码示例

public class MathUtils {
    // 一个公共的静态方法,用于计算两个数的和
    public static int add(int num1, int num2) {
        return num1 + num2;
    }
}

public class PublicExample {
    public static void main(String[] args) {
        // 在任何类中都可以直接调用 MathUtils 类的 public 方法 add
        int result = MathUtils.add(5, 3);
        System.out.println("5 + 3 = " + result);
    }
}

在这个例子中,MathUtils 类的 add 方法被 public 修饰,所以在 PublicExample 类中可以直接调用它,即使这两个类可能不在同一个包中。这展示了 public 权限修饰符的开放性和通用性,使得代码的复用和协作变得更加容易。

六、权限修饰符的综合运用与最佳实践

(一)数据封装与权限修饰符

在设计一个类时,我们应该遵循数据封装的原则,将类的成员变量尽可能地用 private 修饰,然后通过 public 的 getter 和 setter 方法来提供对这些变量的访问和修改接口。这样可以隐藏类的内部实现细节,防止外部类的随意访问和修改,提高代码的安全性和可维护性。例如:

public class Person {
    // 私有成员变量,姓名
    private String name;
    // 私有成员变量,年龄
    private int age;

    // 公共的 getter 方法获取姓名
    public String getName() {
        return name;
    }

    // 公共的 setter 方法设置姓名
    public void setName(String name) {
        this.name = name;
    }

    // 公共的 getter 方法获取年龄
    public int getAge() {
        return age;
    }

    // 公共的 setter 方法设置年龄
    public void setAge(int age) {
        if (age > 0) {
            this.age = age;
        } else {
            System.out.println("年龄必须大于 0");
        }
    }
}

在这个 Person 类中,name 和 age 被 private 修饰,外部类只能通过 getNamesetNamegetAge 和 setAge 这些公共方法来与类进行交互,这样就保证了 Person 类的数据安全性和完整性,同时也提供了一定的灵活性,例如在 setAge 方法中可以添加对年龄的合法性验证逻辑。

(二)继承与权限修饰符的搭配

在继承关系中,父类的 private 成员对子类是不可见的,子类无法直接访问和继承。如果希望子类能够访问和扩展父类的某些成员,应该使用 protected 修饰符。同时,父类的公共接口(public 方法)应该设计得足够通用和稳定,以便子类能够在不破坏父类原有功能的基础上进行重写和扩展。例如:

public class Shape {
    // 形状的颜色,使用 protected 修饰,子类可以访问和修改
    protected String color;

    public Shape(String color) {
        this.color = color;
    }

    // 计算面积的抽象方法,子类必须实现
    public abstract double calculateArea();

    // 一个公共的方法,用于打印形状的信息
    public void printInfo() {
        System.out.println("这是一个 " + color + " 的形状");
    }
}

public class Circle extends Shape {
    private double radius;

    public Circle(String color, double radius) {
        super(color);
        this.radius = radius;
    }

    // 实现父类的抽象方法,计算圆的面积
    @Override
    public double calculateArea() {
        return Math.PI * radius * radius;
    }

    // 重写父类的 printInfo 方法,添加圆的半径信息
    @Override
    public void printInfo() {
        super.printInfo();
        System.out.println("它是一个半径为 " + radius + " 的圆,面积为 " + calculateArea());
    }
}

在这个例子中,Shape 类的 color 成员被 protected 修饰,以便 Circle 子类可以访问和使用它来描述圆的颜色。同时,Shape 类定义了公共的抽象方法 calculateArea 和普通方法 printInfo,子类 Circle 可以根据自身的特点实现 calculateArea 方法,并选择性地重写 printInfo 方法,这样既保证了父类的一般性和抽象性,又允许子类进行具体的实现和扩展,体现了继承与权限修饰符之间的良好搭配。

(三)包的设计与权限修饰符的考虑

在设计 Java 项目的包结构时,也应该充分考虑权限修饰符的作用。将相关的类放在同一个包中,并合理地使用 default 权限修饰符,可以使这些类之间的协作更加紧密和自然,同时又对外隐藏了内部的实现细节。而对于需要对外提供公共接口的类和方法,则应该使用 public 修饰符,以便其他包中的类能够方便地使用它们。例如,在一个电商项目中,可能有一个 product 包,其中包含了 Product 类、ProductDao(数据访问对象)类等,这些类在包内通过 default 权限修饰符相互协作,实现对产品数据的增删改查操作,而 Product 类中的一些公共属性和方法,如产品的名称、价格和获取产品详细信息的方法等,则可以使用 public 修饰符,以便其他包中的业务逻辑类能够访问和使用这些信息来进行订单处理、库存管理等操作。

宝子们,Java 的权限修饰符虽然看起来简单,但在实际的编程中却有着深远的影响。通过合理地运用这些权限修饰符,我们可以构建出结构清晰、安全性高、易于维护和扩展的 Java 代码。希望这篇文章能帮助你深入理解和掌握 Java 权限修饰符的奥秘,在今后的编程之旅中更加得心应手!如果在学习过程中有任何疑问或者想要进一步探讨的问题,随时都可以回来看看这篇文章,或者查阅更多的相关资料哦。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2267820.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

瑞芯微全新芯片平台RK3506优势详解,高集成低功耗,为工业而生 触觉智能测评

RK3506是瑞芯微Rockchip在2024年第四季度全新推出的Arm嵌入式芯片平台&#xff0c;三核Cortex-A7单核Cortex-M0多核异构设计&#xff0c;CPU频率达1.5Ghz, M0 MCU为200Mhz。 而RK3506芯片平台下的工业级芯片型号RK3506J&#xff0c;具备-40-85℃的工业宽温性能、发热量小&#…

AIOps平台的功能对比:如何选择适合的解决方案?

定义与概念 AIOps&#xff0c;即人工智能运维&#xff08;Artificial Intelligence for IT Operations&#xff09;&#xff0c;是将人工智能技术应用于 IT 运维领域&#xff0c;以实现自动化、智能化的运维管理。它通过整合大数据、机器学习等先进技术&#xff0c;对海量运维数…

Python + 深度学习从 0 到 1(03 / 99)

希望对你有帮助呀&#xff01;&#xff01;&#x1f49c;&#x1f49c; 如有更好理解的思路&#xff0c;欢迎大家留言补充 ~ 一起加油叭 &#x1f4a6; 欢迎关注、订阅专栏 【深度学习从 0 到 1】谢谢你的支持&#xff01; ⭐ 神经网络的数据表示 – 张量 你可能对矩阵很熟悉&a…

Lumos学习王佩丰Excel第二十三讲:饼图美化与PPT图表

一、双坐标柱形图的补充知识 1、主次坐标设置 2、主次坐标柱形避让&#xff08;通过增加两个系列&#xff0c;挤压使得两个柱形挨在一起&#xff09; 增加两个系列 将一个系列设置成主坐标轴&#xff0c;另一个设成次坐标轴 调整系列位置 二、饼图美化 1、饼图美化常见设置 …

基于Vue+SSM+SpringCloudAlibaba书籍管理系统

功能要求 一、登录功能&#xff08;http://localhost:8080/#/login&#xff09; 输入账号和密码(admin/admin)进行登录&#xff1a; 如果密码错误&#xff0c;给出提示信息 如果密码正确&#xff0c;跳转到主页 账号或密码错误&#xff1a; 账号密码正确&#xff1a;跳转到…

【优先算法】滑动窗口 --(结合例题讲解解题思路)(C++)

目录 ​编辑 1.什么是滑动窗口&#xff1f; 2. 滑动窗口例题 2.1 例题1&#xff1a;长度最小的子数组 2.1.1 解题思路 2.1.2 方法一&#xff1a;暴力枚举出所有的子数组的和 2.1.3 方法二&#xff1a;使用 “同向双指针” 也就是滑动窗口来进行优化 2.2 例题2&#xff1a;无重…

VS Code 从命令行启动

在 VS Code 中&#xff0c;code 命令允许你在命令行中快速打开文件、文件夹或新窗口。 安装 原本地址&#xff1a;https://code.visualstudio.com/docs/setup/mac 使用 使用 code 命令 打开文件&#xff1a;你可以通过在命令行输入 code 文件名 来直接打开一个文件。 打开文…

微服务-配置管理

文章目录 1.什么是配置管理2.配置共享添加共享配置拉取共享配置 3.配置热更新添加配置到Nacos配置热更新 4.动态路由监听Nacos配置变更 1.什么是配置管理 到目前为止我们已经解决了微服务相关的几个问题&#xff1a; 微服务远程调用微服务注册、发现微服务请求路由、负载均衡…

ArrayList 和LinkedList的区别比较

前言 ‌ArrayList和LinkedList的主要区别在于它们的底层数据结构、性能特点以及适用场景。‌ArrayList和LinkedList从名字分析&#xff0c;他们一个是Array&#xff08;动态数组&#xff09;的数据结构&#xff0c;一个是Linked&#xff08;链表&#xff09;的数据结构&#x…

MySQL--》如何在SQL中巧妙运用函数与约束,优化数据处理与验证?

目录 函数使用 字符串函数 数值函数 日期函数 流程函数 约束 外键约束 约束规则 函数使用 函数是指一段可以直接被另一段程序调用的程序或代码&#xff0c;在mysql当中有许多常见的内置函数&#xff0c;接下来开始对这些内置函数及其作用进行简单的讲解和使用&#xf…

一文大白话讲清楚CSS盒子模型和块级格式化上下文(BFC)

一文大白话讲清楚CSS盒子模型和块级格式化上下文&#xff08;BFC&#xff09; 1.啥是个CSS盒子 鞋盒你家总有吧&#xff0c;方方正正&#xff0c;有长度有高度。css盒子跟这个八九不离十当我们编写html页面时&#xff0c;写了很多的元素&#xff0c;比如"div",&quo…

Docker 快速搭建 GBase 8s数据库服务

1.查看Gbase 8s镜像版本 可以去到docker hub网站搜索&#xff1a;gbase8s liaosnet/gbase8s如果无法访问到该网站&#xff0c;可以通过docker search搜索 docker search gbase8s2.拉取Gbase 8s镜像 以下演示的版本是目前官网最新版本Gbase8sV8.8_3.5.1 docker pull liaosn…

密钥登录服务器

1. 生成 SSH 密钥对 如果您还没有生成密钥对&#xff0c;可以使用以下命令生成&#xff1a; ssh-keygen 在 root 用户的家目录中生成了一个 .ssh 的隐藏目录&#xff0c;内含两个密钥文件&#xff1a;id_rsa 为私钥&#xff0c;id_rsa.pub 为公钥。 在提示时&#xff0c;您可…

王佩丰24节Excel学习笔记——第二十讲:图表基础

【以 Excel2010 系列学习&#xff0c;用 Office LTSC 专业增强版 2021 实践】 【本章技巧】 课件图片有问题&#xff0c;不能随隐藏熟悉各个图表小部件的功能&#xff0c;需要修改都是选中右键进行更改。 一、认识图表中的元素 图表标题&#xff1a;主坐标&#xff08;横坐标&…

华为交换机配置本地端口流量镜像

端口镜像&#xff08;Port Mirroring&#xff09;是网络监控的一种重要技术&#xff0c;通过复制流经特定端口的报文&#xff0c;并将其传送到指定的观察端口&#xff0c;以便对网络流量进行分析和监控。下面将详细介绍如何在华为交换机上配置本地端口镜像&#xff0c;以N:1镜像…

IDEA设置作者信息 日期等

file -> setting 或 ctrl alt s找到如下 然后添加注释即可 可以直接编辑5处的文字&#xff0c;在 author 后放自己的名字即可 /*** author 你的名字* date ${DATE} ${TIME})*/当然 整体不止这些 &#xff0c;看下面的描述中&#xff0c;还有很多其他选项 也可以 4 这…

【stm32can】

can时钟 can波特率计算&#xff08;位同步内容&#xff09; ss是固定的1tq&#xff0c; pts&#xff0c;pbs1&#xff0c;pbs2是用户设定值 同步时间段的理解有误&#xff1f; 原文出处 数据帧 遥控帧

【论文笔记】Contrastive Learning for Sign Language Recognition and Translation

&#x1f34e;个人主页&#xff1a;小嗷犬的个人主页 &#x1f34a;个人网站&#xff1a;小嗷犬的技术小站 &#x1f96d;个人信条&#xff1a;为天地立心&#xff0c;为生民立命&#xff0c;为往圣继绝学&#xff0c;为万世开太平。 基本信息 标题: Contrastive Learning for…

springboot514基于SpringBoot的家电销售展示平台(论文+源码)_kaic

摘 要 传统办法管理信息首先需要花费的时间比较多&#xff0c;其次数据出错率比较高&#xff0c;而且对错误的数据进行更改也比较困难&#xff0c;最后&#xff0c;检索数据费事费力。因此&#xff0c;在计算机上安装家电销售展示平台软件来发挥其高效地信息处理的作用&#x…

【探花交友】day03—MongoDB基础

目录 课程介绍 1、通用设置 1.1 需求分析 1.2 查询通用设置 1.2 陌生人问题 1.3 通知设置 1.4 黑名单管理 2、MongoDB简介 1.1、MongoDB简介 1.2、MongoDB的特点 1.3 数据类型 3、MongoDB入门 2.1、数据库以及表的操作 2.2、新增数据 2.3、更新数据 2.4、删除数…