JAVA 学习·类与方法
不同于 C ,Java 是一门面向对象的编程语言。C++ 也有面向对象的内容,但是 C++ 和 Java 在方法的具体实现上存在区别。
方法的定义
方法(method)是为执行一个复杂操作组合在一起的语句集合。一个类中可以声明多个方法。其语法是采用 BNF 范式(Backus-Naur Form,巴科斯范式)描述的,用来描述计算机语言语法的符号集。
例如,下面是一个求两个整数中最大值的方法max:
public static int max(int num1,int num2){int result = 0;if(num1 > num2)result = num1;elseresult = num2;return result;
}
其中,public和static是修饰符,int是返回值,max是方法名称。
方法签名(Method Signature)是指方法名称+形参列表,如上面方法的签名就是max(int num1,int num2)。一个类中不能包含方法签名相同的多个方法,因为这样在调用方法时编译器不知道要调用哪个。
方法的调用
Java 类中的成员方法可以分为构造方法、类方法和对象方法。
构造方法的调用
构造方法只能在新建一个对象时,由 Java 虚拟机进行调用。创建对象通常是通过类名 对象名 = new 类名(构造函数的参数)建立。比如下面的例子:
class TestConstructor{private int value;public TestConstructor(){this.value = 1;}public TestConstructor(int value){this.value = value;}public int getValue(){return this.value;}
}public class CallConstructor{public static void main(String[ ] args) {TestConstructor tc = new TestConstructor();System.out.println("Value: " + tc.getValue());tc = new TestConstructor(5);System.out.println("Value: " + tc.getValue());}
}
运行的结果是:
Value: 1
Value: 5
this 调用
可以通过this调用该类的其它构造函数,但是必须是构造函数的第一条语句。例如:
class TestConstructor{private int value;public TestConstructor(){this(114);}public TestConstructor(int value){this.value = value;}public int getValue(){return this.value;}
}public class ThisConstructor{public static void main(String[ ] args) {TestConstructor tc = new TestConstructor();System.out.println("Value: " + tc.getValue());}
}
运行的结果为Value: 114。这是因为在调用无参数构造函数时,无参构造函数通过this(114)调用了构造函数TestConstructor(int value),并给其形参传递值value = 114,从而使得value成员初始化为114。
super 调用
一个类还能够通过super调用其父类的构造函数。例如
class TestConstructor{private int value;public TestConstructor(){this(114);}public TestConstructor(int value){this.value = value;}public int getValue(){return this.value;}
}public class SuperConstructor extends TestConstructor{public SuperConstructor(){super(514);}public static void main(String[ ] args) {SuperConstructor sc = new SuperConstructor();System.out.println("Value: " + sc.getValue());}
}
运行的结果为Value: 514。这是因为在调用SuperConstructor类的午餐构造函数时,通过super(514)语句调用了父类TestConstructor中的含参构造函数TestConstructor(int value),并给其形参传递值value = 514,从而使成员value初始化为514。
类方法的调用
类方法就是由static修饰的方法,也称静态方法。静态方法可以通过类名调用,也可以通过对象实例调用。比如下面的代码:
import java.lang.Math;
public class CallStaticMethod{public static void main(String[] args){int a = 114,b = 514;System.out.println(Math.max(a,b));}
}
在这里,调用了 Java 中自带的类Math中的方法max,输出的结果为514。可以看到静态方法max是通过类名.方法名的方式调用的max方法不需要通过创造Math对象math,并通过math.max(a,b)来调用,因为计算一个最大值没有必要依赖对象。
事实上,Java 的开发者也考虑到了这一点,所以将Math类的构造函数设置为私有的,这就导致我们其实也无法创造一个Math类的实例对象。
对象方法的调用
对象方法只能通过实例对象来调用。比如下面的代码:
class Wallet{private int money;Wallet(){money = 0;}public void addMoney(int amount){this.money += amount;}public int getMoney(){return this.money;}
}public class CallObjectMethod{public static void main(String[] args){Wallet wallet = new Wallet();System.out.println("Now we have money: " + wallet.getMoney());wallet.addMoney(520);System.out.println("Then we have money: " + wallet.getMoney());}
}
运行结果为:
Now we have money: 0
Then we have money: 520
可以看到实例方法addMoney和getMoney都是通过对象名.方法名调用的。显然不能通过Wallet.addmoney或者Wallet.getMoney调用这两个方法,因为我可以有多个Wallet对象wallet1,wallet2,...,使用类名.方法名无法知道调用的是哪个Wallet对象。
方法的重载
方法重载(Overloading)是指方法名称相同,但形参列表不同的方法。仅返回类型不同的方法不是合法的重载。一个类中可以包含多个重载的方法(同名的方法可以重载多个版本)。
方法重载实例
方法重载,例如
public class InputCheckTest{public static void CheckInput(String s){System.out.println("You entered a string.");}public static void CheckInput(int i){System.out.println("You entered an integer.");}public static void CheckInput(double d){System.out.println("You entered a double.");}public static void main(String[] args){CheckInput(114514);CheckInput("114514");CheckInput(114514.0);}
}
运行结果:
You entered an integer.
You entered a string.
You entered a double.
有歧义的重载
系统根据我们的输入自动判断调用哪个方法。但是有时候,可能会有多个合适的方法。例如
public class AmbiguousOverloading {public static void main(String[ ] args) {// System.out.println(max(1, 2));}public static double max(int num1, double num2) {return (num1 > num2)?num1:num2;}public static double max(double num1, int num2) {return (num1 > num2)?num1:num2;}
}
将注释符号去掉,上面的代码编译时将产生错误,因为编译器不知道max(1,2)调用的是哪个函数。
包和类的导入
Java 源程序在开头通过import 包名;语句导入其它包(类),可以使用其它包中的类及其方法。有点类似于 C/C++ 中的#include "头文件名"语句。Java 程序在编译时会自动导入java.lang.System类,所以我们在编写源程序时可以直接使用System.out和System.in以及它们的方法。
总的来说,import有两种类型:单类型导入和按需类型导入。
单类型导入
把导入的标识符引入到当前.java文件,因此当前文件里不能定义同名的标识符,类似C++中的 using nm::id; 把名字空间nm的名字id引入到当前代码处。
比如,在包p1中定义了类A:
package p1;
public class A{// some statements...
}
那么在包p2中:
package p2;
import p1.A;//单类型导入,把p1.A引入到当前域
//这个时候当前文件里不能定义A,下面语句编译报错
public class A {//some statements...
}
按需类型导入
不是把包里的标识符都引入到当前.java文件,只是使包里名字都可见,使得我们要使用引入包里的名字时可以不用使用完全限定名,因此在当前.java文件里可以定义与引入包里同名的标识符。但二义性只有当名字被使用时才被检测到。类似于C++里的using nm。
比如,包p1还是和上面一样,此时p2中:
package p2;
import p1.*; //按需导入,没有马上把p1.A引入到当前域
//因此当前文件里可以定义A
public class A {public static void main(String[] args){A a1 = new A(); //这时A是p2.ASystem.out.println(a1 instanceof p2.A); //true//当前域已经定义了A,因此要想使用package p1里的A,只能用完全限定名p1.A a2 = new p1.A();}
}
如果出现了名字冲突,要用完全限定名消除冲突。
类及其方法的可见性修饰符
Java 中的可见性修饰符有private、public和protected,不加可见性修饰符的方法默认访问权限为包级。Java 继承时无继承控制(即都是公有继承,和 C++ 不同),故父类成员继承到派生类时访问权限保持不变(除了私有)。
成员访问控制符的作用:
private: 只能被当前类定义的函数访问。- 包级:无修饰符的成员,只能被同一包中的类访问。
protected:子类、同一包中的类的函数可以访问。public: 所有类的函数都可以访问。
| 访问权限 | 本类 | 本包 | 子类 | 它包 |
|---|---|---|---|---|
public | Yes | Yes | Yes | Yes |
protected | Yes | Yes | Yes | No(非子类时) |
| 包级(默认) | Yes | Yes | No(非本包时) | No |
private | Yes | No | No | No |
其它的都很好理解,只是需要注意一点:子类类体中可以访问从父类继承来的protected成员。但如果子类和父类不在同一个包里,子类里不能访问另外父类实例的protected成员。可以举一个例子说明这一点。我们在p1包里定义C1类:
package p1;
public class C1{protected int u = 3;
}
然后在包p2中,会出现以下情况:
package p2;
import p1.C1
public class C2 extends C1{int u = 5;public static void main(String[] args){System.out.println(u) // OK. u 相当于 this.u,打印结果是 5。System.out.println(super.u) // OK. super.u 指的是父类 C1 中的 u,在子类中能够访问。打印结果是 3。C1 o = new C1();System.out.println(o.u) // ERROR. 虽然这里是 C1 的子类,但是与 C1 不在同一个包中,且 o 是一个另外的父类实例,不能访问 o 的保护成员。}
}
类的继承
Java 中可以用 extends 关键字表示继承,在上面举的例子中也能看到。子类对象是一个父类对象,即子类对象实例 instanceof 父类名的结果为true。
方法覆盖与方法隐藏
如果子类重新定义了从父类中继承的实例方法,称为方法覆盖(Method Override)。如果子类重新定义了从父类中继承的类方法,称为方法隐藏(Method Hidden)。它们具有如下性质:
- 仅当父类方法在子类里是可访问的,该实例方法才能被子类覆盖/隐藏;否则只是定义了一个普通方法而已,不叫作覆盖/隐藏。
- 父类的
final方法不能被子类覆盖/隐藏,否则编译时会报错。 - 在子类函数中可以使用
super调用被覆盖的父类方法。
实例方法的多态性
之所以会产生实例方法的多态性这个概念,是因为父类引用变量可以指向子类对象。例如,如果A是B的父类,那么A o = new B()是可行的。其中,A是变量o的声明类型,编译时对有关变量o的语句进行检查时,都是将o视作声明类型;B是o的运行时类型,在运行的时候,因为o实际指向的对象并不是A类型的,这就会产生多态性。
实例方法的多态性可以通过下面的代码说明:
class A{public void m() {System.out.println("A's m");}public static void s() {System.out.println("A's s");}
}
class B extends A{//覆盖父类实例方法public void m() {System.out.println("B's m");}//隐藏父类静态方法public static void s() {System.out.println("B's s");}
}
public class OverrideDemo {public static void main(String[] args) {A o1 = new B();o1.m(); // B's mo1.s(); // A's s((A)o1).m // B's m,被覆盖的父类实例方法不能再发现B o2 = new B();o2.s // B's s((A)o2).s // A's s,被隐藏的父类静态方法可以再发现}
}
对于上面运行结果的解释是:静态函数没有多态性,函数入口地址在编译时确定,编译时所有的变量都是按照其声明类型;实例方法具有多态性,在运行时时根据实际的运行时类型确定函数入口地址。
相关文章:
JAVA 学习·类与方法
不同于 C ,Java 是一门面向对象的编程语言。C 也有面向对象的内容,但是 C 和 Java 在方法的具体实现上存在区别。 方法的定义 方法(method)是为执行一个复杂操作组合在一起的语句集合。一个类中可以声明多个方法。其语法是采用 BNF 范式(Bac…...
4. python练习题4-水仙花数
4. python练习题4-水仙花数 【目录】 文章目录 4. python练习题4-水仙花数1. 目标任务2. 水仙花数的特点3. 如何判断一个数是否是水仙花数?4. 打印3位水仙花数5. 判断一个数是不是水仙花数6. 列表推导式6. 列表推导式判断一个数是不是水仙花数 【正文】 1. 目标任务…...
【Qt 学习笔记】Qt 开发环境的搭建 | Qt 安装教程
博客主页:Duck Bro 博客主页系列专栏:Qt 专栏关注博主,后期持续更新系列文章如果有错误感谢请大家批评指出,及时修改感谢大家点赞👍收藏⭐评论✍ Qt 开发环境的搭建 | Qt 安装教程 文章编号:Qt 学习笔记 /…...
ids工业相机与电控位移台同步控制及数据采集
通过VS2017和OpenCV,实现ids工业相机与电控位移台同步控制及数据采集 目录项目环境配置代码流程及思路项目架构项目开发运行效果开发关键ids相机配置位移台环境配置相机头文件相机参数设置保存图像函数设置电控位移台头文件电控位移台设置参数最后就是通过main函数进行调用和控…...
景联文科技提供高质量医疗健康AI大模型数据
医疗行业是典型的知识和技术密集型行业,其发展水平直接关系到国民健康和生命质量。 医疗健康AI大模型,作为人工智能的一个分支,能够通过学习大量的数据来生成新的数据实例,在医药研发、医学影像、医疗文本分析等都有广泛的应用前景…...
【Python第三方库】lxml 解析器和xpath路径语言
1.lxml是做什么的 是xml/html的解析器,主要是用来解析和提取html/xml数据 2.lxml语法 使用etree.HTML(html字符串),将字符串转换为Element对象通过使用Element对象.xpath(语法)提取信息,返回的是一个列表的内存地址,需要通过使用索引获取信…...
Java(Lambda、集合)、题解
一、Lambda表达式 标准格式 ()对应方法的形参 ;->固定格式 注意点: Lambda表达式可以用来简化匿名内部类的书写 Lambda表达式只能简化函数式接口的匿名内部类的写法 函数式接口: 有且仅有一个抽象方法的接口叫做函数式接口&…...
Transformer学习: Transformer小模块学习--位置编码,多头自注意力,掩码矩阵
提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 Transformer学习 1 位置编码模块1.1 PE代码1.2 测试PE1.3 原文代码 2 多头自注意力模块2.1 多头自注意力代码2.2 测试多头注意力 3 未来序列掩码矩阵3.1 代码3.2 测试掩码 1 …...
easyexcel 动态列导出
1. 引入easyexcel <dependency><groupId>com.alibaba</groupId><artifactId>easyexcel</artifactId><version>3.2.1</version></dependency> 2.导出write public void export(HttpServletResponse response) {try {String f…...
flink源码编译-job提交
1、启动standalone集群的taskmanager standalone集群中的taskmanager启动类为 TaskManagerRunner 2 打开master启动类 通过 ctrln快捷键,找到、并打开类: org.apache.flink.runtime.taskexecutor.TaskManagerRunner 3 修改运⾏配置 基本完全按照mas…...
Mysql密码修改问题
docker安装mysql,直接拉取镜像,挂载关键目录即可启动,默认3306端口。此时无法直接连接,需要配置密码。docker进入mysql容器中 docker exec -it mysql bash #mysq是容器名称,也可以用容器id通过修改mysql的配置进行免密…...
建独立站,对FP商家有什么好处?
2024年都过去四分之一了,还有许多人对是否投身于跨境独立站领域仍犹豫不决。然而,观望不如实践,如果渴望在跨境电商领域开创一片新天地,那么现在就是行动的最佳时机。 特别是对于FP商家来说,由于电商平台对于黑五类产品…...
使用Postman进行websocket接口测试
因为最近要搞关于基于AI的文本接口测试.需要用到websocket协议,于是看了一下发现postman也可以测而且很方便 位置 File->New->WebSocket 可以看到不止WebSocket还支持其他的各种协议 使用 首先先点击connect进行连接 连接成功之后可以选择多种文本格式添加请求参数 每…...
Android音视频开发 - MediaMetadataRetriever 相关
Android音视频开发 - MediaMetadataRetriever 相关 MediaMetadataRetriever 是android中用于从媒体文件中提取元数据新的类. 可以获取音频,视频和图像文件的各种信息,如时长,标题,封面等. 1:初始化对象 private MediaMetadataRetriever mediaMetadataRetriever new MediaMe…...
注解(Annotation)
10.1 注解概述 10.1.1 什么是注解 注解(Annotation)是从JDK5.0开始引入,以“注解名”在代码中存在。例如: Override Deprecated SuppressWarnings(value”unchecked”) Annotation 可以像修饰符一样被使用,可用于修饰…...
蓝桥杯:七步诗 ← bfs
【题目来源】https://www.lanqiao.cn/problems/3447/learning/【题目描述】 煮豆燃豆苴,豆在釜中泣。本是同根生,相煎何太急?---曹植 所以,这道题目关乎豆子! 话说赤壁之战结束后,曹操的船舰被刘备烧了,引领军队从华容…...
Vue 如何快速上手
目录 1. Vue 是什么 (概念) 1.1. Vue 的两种使用方式 1.2. 优点 1.3. 缺点 2. 创建 Vue 实例,初始化渲染 2.1. 步骤(核心步骤 4步) 2.2. 练习——创建一个Vue实例 3. 插值表达式 {{ }} 3.1. 介绍 3.2. 作用…...
Vue3:组件间通信-provide和inject实现祖先组件与后代组件间直接通信
一、情景说明 我们学习了很多的组件间通信 这里在学习一种,祖先组件与后代组件间通信的技术 这里的后代,可以是多层继承关系,子组件,子子组件,子子子组件等等。 在祖先组件中通过provide配置向后代组件提供数据在后代…...
微信小程序——小程序和页面生命周期详解
小程序的生命周期 小程序的生命周期主要分为以下几个阶段: 创建(onLoad): 当小程序启动时,或者从其他页面跳转到当前页面时,会触发 onLoad 生命周期函数。 这个阶段通常用于初始化页面数据,从服…...
android studio中添加module依赖
android常用的三种依赖 库依赖(Library dependency):以访问网址的形式将依赖库相应版本下载到本地; 文件依赖(File dependency): 将下载下来的依赖库以.jar文件的形式添加依赖. module依赖(Modu…...
内存分配函数malloc kmalloc vmalloc
内存分配函数malloc kmalloc vmalloc malloc实现步骤: 1)请求大小调整:首先,malloc 需要调整用户请求的大小,以适应内部数据结构(例如,可能需要存储额外的元数据)。通常,这包括对齐调整,确保分配的内存地址满足特定硬件要求(如对齐到8字节或16字节边界)。 2)空闲…...
Vue3 + Element Plus + TypeScript中el-transfer穿梭框组件使用详解及示例
使用详解 Element Plus 的 el-transfer 组件是一个强大的穿梭框组件,常用于在两个集合之间进行数据转移,如权限分配、数据选择等场景。下面我将详细介绍其用法并提供一个完整示例。 核心特性与用法 基本属性 v-model:绑定右侧列表的值&…...
使用分级同态加密防御梯度泄漏
抽象 联邦学习 (FL) 支持跨分布式客户端进行协作模型训练,而无需共享原始数据,这使其成为在互联和自动驾驶汽车 (CAV) 等领域保护隐私的机器学习的一种很有前途的方法。然而,最近的研究表明&…...
【android bluetooth 框架分析 04】【bt-framework 层详解 1】【BluetoothProperties介绍】
1. BluetoothProperties介绍 libsysprop/srcs/android/sysprop/BluetoothProperties.sysprop BluetoothProperties.sysprop 是 Android AOSP 中的一种 系统属性定义文件(System Property Definition File),用于声明和管理 Bluetooth 模块相…...
C++.OpenGL (10/64)基础光照(Basic Lighting)
基础光照(Basic Lighting) 冯氏光照模型(Phong Lighting Model) #mermaid-svg-GLdskXwWINxNGHso {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg-GLdskXwWINxNGHso .error-icon{fill:#552222;}#mermaid-svg-GLd…...
Spring AI与Spring Modulith核心技术解析
Spring AI核心架构解析 Spring AI(https://spring.io/projects/spring-ai)作为Spring生态中的AI集成框架,其核心设计理念是通过模块化架构降低AI应用的开发复杂度。与Python生态中的LangChain/LlamaIndex等工具类似,但特别为多语…...
Unity | AmplifyShaderEditor插件基础(第七集:平面波动shader)
目录 一、👋🏻前言 二、😈sinx波动的基本原理 三、😈波动起来 1.sinx节点介绍 2.vertexPosition 3.集成Vector3 a.节点Append b.连起来 4.波动起来 a.波动的原理 b.时间节点 c.sinx的处理 四、🌊波动优化…...
免费PDF转图片工具
免费PDF转图片工具 一款简单易用的PDF转图片工具,可以将PDF文件快速转换为高质量PNG图片。无需安装复杂的软件,也不需要在线上传文件,保护您的隐私。 工具截图 主要特点 🚀 快速转换:本地转换,无需等待上…...
基于Springboot+Vue的办公管理系统
角色: 管理员、员工 技术: 后端: SpringBoot, Vue2, MySQL, Mybatis-Plus 前端: Vue2, Element-UI, Axios, Echarts, Vue-Router 核心功能: 该办公管理系统是一个综合性的企业内部管理平台,旨在提升企业运营效率和员工管理水…...
Ubuntu Cursor升级成v1.0
0. 当前版本低 使用当前 Cursor v0.50时 GitHub Copilot Chat 打不开,快捷键也不好用,当看到 Cursor 升级后,还是蛮高兴的 1. 下载 Cursor 下载地址:https://www.cursor.com/cn/downloads 点击下载 Linux (x64) ,…...
