架构图
前言
有鑑于各个地区的专业用语不同,所以本文会尽量使用英文来呈现有差异的部分,还请见谅
方法简介
甚么是方法
方法就是用来解决特殊需求的一个功能模块、程式语句的集合,把需要重複使用的功能包装到方法裡面。例如我们最常使用的System.out.println()
,就是调用System
类中实例化的对象out
中的方法println()
在java中方法一定存在于某个类之中,这点跟C/C++, Python有点不同
方法格式
一个方法的编写可以参考下列格式:
修饰符 返回值类型 方法名(数据类型1 参数名1, 数据类型2 参数名2){
// 方法主体
return 返回值;
}
- 修饰符
- 告诉compiler如何调用该方法(option)
- 例如封装性的
public
,private
,静态方法的static
- 返回类型
- 决定方法执行完成后的返回值数据类型
- 例如基本数据类型与引用数据类型
void
类型则无返回值
- 方法名
- 方法的名称,通常有约定俗成的规范
- 参数列表
- 调用该方法时需要传入的数据类型与数量
- 例如基本数据类型与引用数据类型
- 也可以不传入任何参数
- 方法体
- 方法的程式逻辑区段
- 返回值
- 方法的返回值
- 若返回类型为
void
,则可以不填
举例说明,下面是一个真实的方法案例:
方法的命名
方法的命名通常与变数一样,採用小驼峰法也就是说当方法名为单一英文单字时要求小写,若是两个英文单字的组合,第一个单字需要小写,第二个英文单字开头大写
另外两种英文单字的组合通常是:
- 动词缩写
- 例如
get
,set
,update
,remove
等 - 目的: 为了完成指定动作
- 例如
- 以动词 + 名词方式命名
- 例如
ensureCapacity
,displayMenu
,initializaTable
等 - 目的: 为了完成指定动作,并指名操作目标
- 例如
- 助动词 + 动词/名词
- 例如
shouldMigrate
,canInput
,mayDump
等 - 目的: 通常涉及到使用时机的动作
- 例如
- 使用be动词开头 + 名词/形容词
- 例如
isValid
,isOpen
,isFinish
等 - 目的: 用来判断当前的行为是否合法
- 例如
- 用来表达长度、容量、大小可以使用名词
- 例如
length
,size
,width
等 - 目的: 用来获取、运算指定参数属性
- 例如
不过说到底这些命名规则共同目标都是为了让开发者能快速了解方法的作用,太简洁不易理解;太详细容易陷入冗长,该怎么拿捏还是要看团队的共识,如果想更了解命名规则的话可以参考这篇
方法的调用
方法的调用主要取决于是否有返回值,以及方法位置
若方法调用具有返回值,则该方法实际上被视为一个数值,当控制权藉由方法返回给调用语句时,通常会将返回值赋值给一个左值变数(也可以选择不进行赋值)
返回值类型void
则代表无返回值类型,调用时直接使用,不需要进行赋值配置,因为它实际上就是一条语句
另外主方法main也是一个返回类型void
的方法,本质上它与其他方法没有任何差异,只不过它是由JVM调用,代表程式的入口,main方法结束后整个程式便结束了,所以不需要回传任何数值
下面程式范例介绍方法的调用方式:
public class Main
{
public static int testOne(int num){
return num + 10;
}
public static void testTwo(int num){
num++;
}
public static void main(String[] args) {
int sum=0;
sum = testOne(sum); // 有返回值
testOne(sum); // 有返回值
testTwo(sum); // 无返回值
}
}
调用的方法若位于不同的类当中,则需要先创建对象,实例化后再进行调用。相同类中的方法可以直接调用,但须要注意static
方法只能调用同类中的static
方法(后面章节会提到)
主方法中若想调用其他类中的方法,需要先实例化操作:
public class Main
{
public static void read(){
System.out.println("class Main read");
}
public static void main(String[] args) {
Student stu = new Student();
stu.read();
read();
}
}
Student类中的read
方法:
public class Student{
public void read(){
System.out.println("class Student read");
}
}
方法的结束
有开始必定有结束,一个方法将控制权返回给调用方通常会满足下面三个条件之一:
- 方法执行完所有的语句
- 执行
return
- 抛出异常
scope
scope就是在程式执行区段中一个变数可以被引用的范围。一个变数的作用范围可以藉由修饰符与所处程式码区段,在编译时决定
而在方法中我们使用的变数类型为局部变数,它储存在栈空间中(stack)。一个方法内的局部变数在调用方法时生成,返回时销毁。在方法体内我们可以使用{}
另闢一个程式码区块,不同区块中可以宣告同名的局部变数,因为他们的scope范围各自在退出括号后结束,因此不冲突,例如:
方法中在执行的过程中维护了一个称为局部变数表的表格,如果该变数的执行区段一结束,该变数就会从该表中删除。相反的,若一个变数还未被删除,就不允许再宣告一个同名变数
在方法test中宣告的temp还未被释放就宣告一个同名的变数,会产生重複宣告的错误,例如下面的例子:
方法多载
多载简介
多载(overloading)就是一个类当中具有多个同名的方法,但会具有以下差异:
- 传入的参数类型不同
- 参数列表数量不同
- 参数顺序不同
换句话说就是两个方法的方法签名(Method Signature)不同
多载方法适用于功能相同但是输入参数不同的情况。也就是说会调用哪个多载方法,需要看使用者传入的引数(Argument)决定,多载能够让开发者不用为了参数不同再去创建一个具有相似功能但名称不同的方法
例如以下程式码范例,主方法调用的addSum
方法会依照上述所说的三种差异而使用不同的多载方法:
public class Main{
public static int addSum(int num1, int num2){
System.out.print("方法一: ");
return num1 + num2;
}
public static int addSum(int num1, int num2, int num3){
System.out.print("方法二: ");
return num1 + num2 + num3;
}
public static double addSum(double num1, double num2, double num3){
System.out.print("方法三: ");
return num1 + num2 + num3;
}
public static double addSum(double num1, int num2){
System.out.print("方法四: ");
return num1 + num2;
}
public static double addSum(int num1, double num2){
System.out.print("方法五: ");
return num1 + num2;
}
public static void main(String[] args) {
System.out.println("sum = " + addSum(3, 1));
/*参数数量不同*/
System.out.println("sum = " + addSum(3.5, 1.2, 10.0));
/*参数类型不同*/
System.out.println("sum = " + addSum(3, 1, 10));
/*顺序不同*/
System.out.println("sum = " + addSum(3, 1.2));
System.out.println("sum = " + addSum(3.5, 1));
}
}
输出结果:
方法一: sum = 4
方法三: sum