当前位置: 首页 > news >正文

java篇 类的进阶0x06:可见性修饰符(访问修饰符)

文章目录

  • 可见性修饰符(访问修饰符)
    • 成员变量都应该是 private
    • 构造方法可以是 private 的
    • public 修饰的东西尽量不要改动
    • 非 public 的类,类名可以不和文件名相同
    • protected 继承专属的访问控制

可见性修饰符(访问修饰符)

可见性修饰符用在 类、成员方法、构造方法、静态方法、静态变量成员变量上,其可见性的范围是一样的。

只有 局部变量 和 参数 没有访问控制符。所有可能被分享的,被使用到别的地方的,都可以使用访问修饰符来控制可被访问的程度。

  • public: 全局可见,对所有包都可见
  • 缺省:当前包可见
  • private:当前类可见
  • protected【专门为继承打造】:缺省(default)+ 对子类可见

注意:

  • privateprotected 不能用于修饰类与接口。
  • 缺省 虽然可以用于修饰类,但是仅仅是对包中的其他类可见,不同的包的类,并不能实现通过 import 来导入这个类,也无法继承这个类。

成员变量都应该是 private

成员变量应该都声明为 private

  • 如果要读写这些成员变量,最好使用 get、set 方法,这些方法应该是 public 的。这样的好处是,如果有需要,可以通过添加一些条件判断的代码,检查每个属性值是否合法。

构造方法可以是 private 的

构造方法如果是 private 的,那么就只有当前的类可以调用这个构造方法。

有些时候,会把所有的构造方法都定义成 private 的,然后使用静态方法调用构造方法(因为该静态方法是 public 的,可以被别的类调用,而该静态方法又和 private的构造方法是同一个类中,可以调用该构造方法,所以就等于通过 public 的静态方法调用了 private 的构造方法)。

  • 这样的好处是可以通过代码,检查某个属性值是否合法。等于加了一层过滤,在静态方法中做一些判断,避免直接使用构造方法创建属性是非法的实例。(虽然在构造器中也可以加过滤语句,但实际上调用构造器时,已经在建造实例了,也已经创建出来了,只是在赋值时作过滤,而如果是在静态方法中作过滤,则直接就不会去调用构造器去生成非法实例)

    public class TestClass{private TestClass(String name,int age){						// 将构造方法设置为 privatethis.name = name;this.age = age;}public static TestClass createObj(String name,int age){		// 将静态方法设置为 publicif(age<=0){												// 这样可以加一层过滤,避免传递非法值,构建非法实例return null;}else{// return this(name,age);									// 并不能调用 this(),否则报错,因为 this只能出现在构造器中,并且必须是构造器的第一行代码。这里只是一个静态方法,无法调用this()return new TestClass(name,age);}}
    }// 调用方
    import com.test.TestClass;public class TestUse{public static void main(String[] args){TestClass a = createObj("Tom",13);			// 调用 public 的静态方法来返回一个 TestClass 实例对象}
    }
    

public 修饰的东西尽量不要改动

public 的方法类似一种约定,因为 public 就意味着外面的代码可以使用这个方法,也就意味着你不能再对这个方法随意更改,比如不应该更改方法的签名、返回值(但可以优化方法体内的代码逻辑),因为一旦修改,可能外面的代码就可能要跟着修改,否则会出现错误。

所以,尤其是某些 java 的常用类,其中定义的方法会很小心地使用 public。我们知道成员变量都应该定义成 private,然后再用 public 的方法去操作它们。但很多类内部的操作,不需要外部去使用的,也可以定义成 private。定义成 public 的话,你就得保证这个方法,在往后不同的 java 版本中,它的方法签名、返回值不能变,否则就可能出很多问题。

public 方法是我们确定可以长期对外提供功能的。访问修饰符的目的不仅仅是为了限制别人的使用,更加是为了规范地提供一套稳定的方法供别人使用。

而对于 private 的方法,因为类外面调用不到,所以无论怎么改,也不会影响(直接影响)类外面的代码。

非 public 的类,类名可以不和文件名相同

public 的类,类名可以不和文件名相同。但因为是非 public,这个类最多就只能被同一个包中的其他类所引用。

疑问1: 一个 java class 文件中是否可以包含多个 class?

经过实验,一个 java class(.java) 文件中是可以同时包含(/定义)多个类的,但只能有一个公共类,并且只要有公共类(public class),这个class 文件的文件名就得和这个公共类名一摸一样(大小写一致),可以有如下两个情况:

  • 只有一个公共类:TestClass 文件,包含:class A、class B、public TestClass、class C、…

    • 这种还比较常见,比如说 java 自带的 Math.java 文件,包含了 public class Math,同时还包含了多个非公共类,当然这些类都是相关的,服务于 Math 类的。
  • 没有公共类:Test 文件,包含:class A、class B、TestClass、class C、…

疑问2: main 方法只能出现在公共类中么?同一个文件如果可以包含多个类,是否也可以包含多个 main 方法?

经过实验,main 方法既可以出现在公共类(public)中,也可以出现在非公共类中。并且一个 .java文件中可以同时有多个 main 方法,每个类拥有一个 main 方法(哪怕是这个.java 文件同时包含一个公共类与多个非公共类),在 IEDA 中将鼠标定位到哪个类右键,就可以选择执行相应类的 main 方法。

protected 继承专属的访问控制

protected 可见性:default + 对子类可见。

  • 即,对同一个包可见,且对子类可见(即便子类不在同一个包)
// org.test.A 包中
public class A{protected int age = 10;String name = "Tom";
}// org.test 包中
public class B extends A{						// 多做一层继承,是为了说明 protected 可见的子类是所有子类,而非仅仅是直接子类}// org.test 包中
public class C extends B{public void getAge(){System.out.println(this.age);}
// 若不注释下面的 getName 方法,编译时会报错,因为找不到 this.name 属性,因为 name 是缺省访问修饰符,只能同一个包中可见。
//    public void getName(){						
//        System.out.println(this.name);
//    }
}// org.test 包中
// 调用类
public class TestUse{public static void main(String[] args){C c = new C();c.getAge();									// 10System.out.println(c.age);					// 报错,因为 TestUse 既不是 A 的子类,也不和 A 在同一个包中,所以无法看到 protected 修复符定义的 .age 属性。}
}// 若将调用类 TestUse 移动到 org.test.A 包中
public class TestUse{public static void main(String[] args){C c = new C();c.getAge();									// 10System.out.println(c.age);					// 10}
}

子类覆盖父类的方法,不可以用可见性更低的修饰符,但是可以用更高的修饰符。

public > protected > default(缺省) > private

不能用可见性更低的修饰符来覆盖的原因:

public class A{protected void sayHi(){System.out.println("调用的是 A 的 sayHi");}
}
public class B extends A{private void sayHi(){System.out.println("调用的是 B 的 sayHi");}
}
public class TestUse{public static void main(String[] args){A a = new B();a.sayHi();			// 此时因为覆盖,实际调用的应该是 B 中定义的 sayHi。但现在 B 中定义的 sayHi 却是 private,即无法被其他类访问,这就与多态冲突了。}
}

既然你覆盖了父类方法,父类的引用在指向你这个对象实例的时候,就要访问你覆盖父类的这个方法,如果你此时访问修饰符让我访问不了,这样就矛盾了。所以你非要用可见性更低的访问修饰符来覆盖,java 就直接给你报错。

所以若用 protected 来修饰方法,则子类若想覆盖该方法需要至少是 protected,或者 public。

相关文章:

java篇 类的进阶0x06:可见性修饰符(访问修饰符)

文章目录 可见性修饰符&#xff08;访问修饰符&#xff09;成员变量都应该是 private构造方法可以是 private 的public 修饰的东西尽量不要改动非 public 的类&#xff0c;类名可以不和文件名相同protected 继承专属的访问控制 可见性修饰符&#xff08;访问修饰符&#xff09;…...

Java 贪心算法经典问题解决

文章目录 分金条题目思路代码实现测试用例以及结果输出 花费资金做项目最大收益题目思路代码实现测试用例以及结果输出 预定会议室题目思路代码实现测试用例以及结果输出 取中位数题目思路代码实现测试用例以及结果输出 最低字典序题目思路代码实现测试用例以及结果输出 结语 分…...

所有docker命令无效,解决办法

目录 ■前言 今天使用docker时&#xff0c;所有命令无效 ■解决办法如下 1.停止docker服务 2.查看状态 3.删除之前的docker相关的文件 4.再次查看状态 5.使用相关命令 &#xff08;好用了&#xff09; 6.重新下载镜像 ■前言 今天使用docker时&#xff0c;所有命令无…...

系列一、创建者模式

一、概述 创建者模式的主要关注点是"怎样创建对象?"&#xff0c;它的主要特点是"将对象的创建与使用分离"。这样可以降低系统的耦合度&#xff0c;使用者不需要关注对象的创建细节。 二、分类 单例模式工厂方法模式抽象工厂模式原型模式建造者模式...

数据库系列:覆盖索引和规避回表

1 介绍 在MySQL数据库查询过程中&#xff0c;索引覆盖和避免不必要的回表&#xff0c;是减少检索步骤&#xff0c;提高执行效率的有效手段。下面从这两个角度分析如何进行MySQL检索提效。 2 数据准备 模拟一个500w数据容量的部门表 emp&#xff0c;表结构如下&#xff0c;并…...

java Spring Boot上线运维 启动jar时控制台调整零时变量

前面的文章 java 打包Spring Boot项目&#xff0c;并运行在windows系统中和将Spring Boot项目打包部署到阿里云linux服务器讲述了Spring Boot项目打包部署的过程 但是 这里 我们可能会遇到一种情况 此时 我们服务器 java项目占用了 80端口 但我们需要放上去一个更重要的东西&am…...

java后端校验

Java 后端数据校验 一、概述 当我们想提供可靠的 API 接口&#xff0c;对参数的校验&#xff0c;以保证最终数据入库的正确性&#xff0c;是 必不可少 的活。比如下图就是 我们一个项目里 新增一个菜单校验 参数的函数&#xff0c;写了一大堆的 if else 进行校验&#xff0c;…...

PowerPoint如何修改“默认保存路径”?

很多时候&#xff0c;我们做好PPT后都要保存&#xff0c;一般会保存在创建PPT的文件夹里&#xff0c;或者另外设置保存的路径。 如果经常需要制作PPT&#xff0c;又不想每次都要重新选择保存位置&#xff0c;我们可以创建或修改“默认保存路径”&#xff0c;这样每次关闭PPT后…...

【PMP】有没有项目经理能看得懂这九张图?求挑战

这九张图&#xff0c;全是圈圈我的肺腑之言啊&#xff01;谁痛谁知道&#xff01; 做技术时&#xff0c;就想着30岁就转管理&#xff0c;管理岗位赚得多&#xff0c;结果发现全是烟雾弹。 做技术和代码打交道&#xff0c;做管理跟人打交道。天天开不完的会、说不完的话&#xf…...

ES6学习记录—自己记录一直更新版

1. 什么是ECMA 全称&#xff1a;European computer manufacturers association欧洲计算机制造联合会; 2、它的标准名单中的&#xff1a;ECMA — 262脚本语言的规范&#xff1a;规范化脚本语言&#xff0c;叫ECMAScript ( 一定要记住)&#xff1b;像ES5 ES6就是这样来的&#xf…...

linux操作gpio的一些记录

在linux里面使用GPIO的一些知识点记录如下&#xff1a; 一、驱动里面操作GPIO 在linux内核里面如果 pinctrl 子系统将一个 PIN 复用为 GPIO 的话&#xff0c;那么就可以用gpio 子系统提供的 API 函数操做gpio&#xff0c;比如设置 GPIO为输入输出&#xff0c;读取 GPIO 的值等…...

目前新能源汽车充电桩的发展受到哪些不利因素的影响?

目前新能源汽车充电桩的发展受到哪些不利因素的影响? 一是安装难&#xff0c;很多老旧小区没有充电桩配套施工规范&#xff0c;充电桩建设比较难&#xff0c;受到充电容量不足电表箱供电等局限性的制约&#xff0c;同时缺乏充电桩配套设施的统一规划&#xff0c;小区内只能安装…...

jenkins

Gitlab添加钩子 测试钩子 添加完成后&#xff0c;下面会出现钩子选择。点击test中的&#xff0c;push event。 出现successful&#xff0c;既添加成功。 如果添加失败&#xff0c;报错&#xff0c;更改Network...

基于深度学习的图像分割技术探究

导言&#xff1a; 图像分割是计算机视觉领域的重要任务&#xff0c;旨在将图像划分为不同的语义区域&#xff0c;实现对图像中感兴趣物体的定位和提取。深度学习作为图像分割的新兴技术&#xff0c;通过卷积神经网络&#xff08;CNN&#xff09;等模型&#xff0c;取得了显著的…...

【c++】vector的使用与模拟实现

&#x1f680;write in front&#x1f680; &#x1f4dc;所属专栏&#xff1a;初阶数据结构 &#x1f6f0;️博客主页&#xff1a;睿睿的博客主页 &#x1f6f0;️代码仓库&#xff1a;&#x1f389;VS2022_C语言仓库 &#x1f3a1;您的点赞、关注、收藏、评论&#xff0c;是对…...

记录安装stable diffusion webui时,出现的gfpgan安装卡住的问题

参考链接&#xff1a;(145条消息) 使用stable diffusion webui时&#xff0c;安装gfpgan失败的解决方案&#xff08;windows下的操作&#xff09;_新时代原始人的博客-CSDN博客...

【开发环境】Windows下搭建TVM编译器

关于搭建TVM编译器的官方文档&#xff1a;Install from Source — tvm 0.14.dev0 documentation (apache.org) 1. 安装Anaconda 首先我们需要安装Anaconda&#xff0c;因为其中包含着我们所需要的各类依赖&#xff1a; 进入Anaconda官网https://www.anaconda.com/products/d…...

了解Unity编辑器之组件篇Video(二)

Video Player组件&#xff1a;用于在游戏中播放视频的组件。它提供了一系列属性来控制视频的播放、显示和交互。 1.Source&#xff08;视频源&#xff09;&#xff1a;用于指定视频的来源。可以选择两种不同的视频源类型&#xff1a; &#xff08;1&#xff09;Vieo Clip&#…...

安全杂记 - 状态码,DNS,编码

目录 1.状态码2.DNS解析过程3.URL编码4.HTML实体编码5.FORM表单 1.状态码 200 - 请求成功 301 - 资源&#xff08;网页等&#xff09;被永久转移到其它URL 302 - 临时移动。与301类似。但资源只是临时被移动。客户端应继续使用原有URI 304 - 未修改。所请求的资源未修改&#…...

微信小程序 Page页面

新建页面只需要在app.json配置好路径&#xff0c;编译器自动新增了页面 项目首页&#xff0c;在app.json哪个页面是第一位&#xff0c;哪个页面就是小程序首页...

web vue 项目 Docker化部署

Web 项目 Docker 化部署详细教程 目录 Web 项目 Docker 化部署概述Dockerfile 详解 构建阶段生产阶段 构建和运行 Docker 镜像 1. Web 项目 Docker 化部署概述 Docker 化部署的主要步骤分为以下几个阶段&#xff1a; 构建阶段&#xff08;Build Stage&#xff09;&#xff1a…...

云原生核心技术 (7/12): K8s 核心概念白话解读(上):Pod 和 Deployment 究竟是什么?

大家好&#xff0c;欢迎来到《云原生核心技术》系列的第七篇&#xff01; 在上一篇&#xff0c;我们成功地使用 Minikube 或 kind 在自己的电脑上搭建起了一个迷你但功能完备的 Kubernetes 集群。现在&#xff0c;我们就像一个拥有了一块崭新数字土地的农场主&#xff0c;是时…...

【Oracle APEX开发小技巧12】

有如下需求&#xff1a; 有一个问题反馈页面&#xff0c;要实现在apex页面展示能直观看到反馈时间超过7天未处理的数据&#xff0c;方便管理员及时处理反馈。 我的方法&#xff1a;直接将逻辑写在SQL中&#xff0c;这样可以直接在页面展示 完整代码&#xff1a; SELECTSF.FE…...

Redis相关知识总结(缓存雪崩,缓存穿透,缓存击穿,Redis实现分布式锁,如何保持数据库和缓存一致)

文章目录 1.什么是Redis&#xff1f;2.为什么要使用redis作为mysql的缓存&#xff1f;3.什么是缓存雪崩、缓存穿透、缓存击穿&#xff1f;3.1缓存雪崩3.1.1 大量缓存同时过期3.1.2 Redis宕机 3.2 缓存击穿3.3 缓存穿透3.4 总结 4. 数据库和缓存如何保持一致性5. Redis实现分布式…...

python如何将word的doc另存为docx

将 DOCX 文件另存为 DOCX 格式&#xff08;Python 实现&#xff09; 在 Python 中&#xff0c;你可以使用 python-docx 库来操作 Word 文档。不过需要注意的是&#xff0c;.doc 是旧的 Word 格式&#xff0c;而 .docx 是新的基于 XML 的格式。python-docx 只能处理 .docx 格式…...

linux 下常用变更-8

1、删除普通用户 查询用户初始UID和GIDls -l /home/ ###家目录中查看UID cat /etc/group ###此文件查看GID删除用户1.编辑文件 /etc/passwd 找到对应的行&#xff0c;YW343:x:0:0::/home/YW343:/bin/bash 2.将标红的位置修改为用户对应初始UID和GID&#xff1a; YW3…...

让回归模型不再被异常值“带跑偏“,MSE和Cauchy损失函数在噪声数据环境下的实战对比

在机器学习的回归分析中&#xff0c;损失函数的选择对模型性能具有决定性影响。均方误差&#xff08;MSE&#xff09;作为经典的损失函数&#xff0c;在处理干净数据时表现优异&#xff0c;但在面对包含异常值的噪声数据时&#xff0c;其对大误差的二次惩罚机制往往导致模型参数…...

网站指纹识别

网站指纹识别 网站的最基本组成&#xff1a;服务器&#xff08;操作系统&#xff09;、中间件&#xff08;web容器&#xff09;、脚本语言、数据厍 为什么要了解这些&#xff1f;举个例子&#xff1a;发现了一个文件读取漏洞&#xff0c;我们需要读/etc/passwd&#xff0c;如…...

【Go语言基础【12】】指针:声明、取地址、解引用

文章目录 零、概述&#xff1a;指针 vs. 引用&#xff08;类比其他语言&#xff09;一、指针基础概念二、指针声明与初始化三、指针操作符1. &&#xff1a;取地址&#xff08;拿到内存地址&#xff09;2. *&#xff1a;解引用&#xff08;拿到值&#xff09; 四、空指针&am…...

MySQL JOIN 表过多的优化思路

当 MySQL 查询涉及大量表 JOIN 时&#xff0c;性能会显著下降。以下是优化思路和简易实现方法&#xff1a; 一、核心优化思路 减少 JOIN 数量 数据冗余&#xff1a;添加必要的冗余字段&#xff08;如订单表直接存储用户名&#xff09;合并表&#xff1a;将频繁关联的小表合并成…...