我正在参加「掘金·启航计划」
什么是方法?
方法的本质就是一个代码片段, 类似于 C 语言中的 函数。它存在的意义为:
- 是能够模块化的组织代码(当代码规模比较复杂的时候)。
- 做到代码被重复使用, 一份代码可以在多个位置使用。
- 让代码更好理解更简单。
- 直接调用现有方法开发, 不必重复造轮子。
请看问题:
- 输出 1! + 2! + 3! + 4! + 5! 的值。
传统解法:
int sum = 0;
for (int i = 1; i <= 5; i++) {
int tmp = 1;
for (int j = 1; j <= i; j++) {
tmp *= j;
}
sum += tmp;
}
System.out.println("sum = " + sum);
这段代码中使用了双重循环, 还比较容易写错。这个场景我们就可以使用方法来优化这个代码。
基本语法
方法的定义:
public static 方法返回值 方法名称([参数类型 形参 ...]){
方法体代码;
[return 返回值];
}
方法的调用:
返回值变量 = 方法名称(实参...);
具体案例就使用上面 阶乘之和 的例题来讲解,代码可以修改为:
class Test {
//主(main)方法
public static void main(String[] args) {
int sum = 0;
for (int i = 1; i <= 5; i++) {
sum += factor(i);
}
System.out.println("sum = " + sum);
}
//专门计算阶乘的方法
public static int factor(int n) {
System.out.println("计算 n 的阶乘中! n = " + n);
int result = 1;
for (int i = 1; i <= n; i++) {
result *= i;
}
return result;
}
}
// 执行结果
计算 n 的阶乘中! n = 1
计算 n 的阶乘中! n = 2
计算 n 的阶乘中! n = 3
计算 n 的阶乘中! n = 4
计算 n 的阶乘中! n = 5
sum = 153
我们可以看到:使用方法,直观逻辑上避免了使用二重循环,让代码更简单清晰,可读性更高。
使用规则
- 定义方法的时候,不会执行方法的代码.,只有==调用==的时候才会执行。
- 当方法被调用的时候,会将实参赋值给形参。
- 参数传递完毕后, 就会执行到方法体代码。
- 当方法执行完毕之后(遇到
return
语句),就执行完毕, 回到方法调用位置,按照执行流继续往下执行。 - 一个方法可以被多次调用。
方法的重载
有些时候我们需要用一个函数同时兼容多种参数的情况, 我们就可以使用到方法重载。
例如以下场景:
class Test {
public static void main(String[] args) {
int a = 10;
int b = 20;
int ret = add(a, b); //int类型数据的加法
System.out.println("ret = " + ret);
double a2 = 10.5;
double b2 = 20.5;
double ret2 = add(a2, b2); //double类型数据的加法
System.out.println("ret2 = " + ret2);
}
public static int add(int x, int y) {
return x + y;
}
}
// 编译出错
Test.java:13: 错误: 不兼容的类型: 从double转换到int可能会有损失
double ret2 = add(a2, b2);
^
究其原因是因为参数类型不匹配导致的,所以不能使用现有的 add 方法。
那我们考虑创建两个对应的方法来操作:
public static int addInt(int x, int y) {
return x + y;
}
public static double addDouble(double x, double y) {
return x + y;
}
说可行也确实可行,但如果参数类型很多,就要起许多独特的方法名,对用户也并不友好,不如全部都叫做 add ,统一使用。所以就用到方法的重载。
class Test {
public static void main(String[] args) {
int a = 10;
int b = 20;
int ret = add(a, b);
System.out.println("ret = " + ret);
double a2 = 10.5;
double b2 = 20.5;
double ret2 = add(a2, b2);
System.out.println("ret2 = " + ret2);
double a3 = 10.5;
double b3 = 10.5;
double c3 = 20.5;
double ret3 = add(a3, b3, c3);
System.out.println("ret3 = " + ret3);
}
@Overload //类内部方法-重载
public static int add(int x, int y) {
return x + y;
}
@Overload
public static double add(double x, double y) {
return x + y;
}
@Overload
public static double add(double x, double y, double z) {
return x + y + z;
}
}
方法的名字都叫 add
,但是有的 add 是计算 int
相加, 有的是 double
相加; 有的计算2
个数字相加, 有的是计算3
个数字相加。
同一个方法名字, 提供不同版本的实现, 称为方法的重载。
@Overload 为重载的标签,不必须,但最好进行标记以便阅读程序。
重载的规则
针对同一个类:
- 方法名相同
- 方法的参数不同(参数个数或者参数类型)
- 方法的返回值类型不影响重载。请看代码:
class Test {
public static void main(String[] args) {
int a = 10;
int b = 20;
int ret = add(a, b);
System.out.println("ret = " + ret);
}
public static int add(int x, int y) {
return x + y;
}
public static double add(int x, int y) {
return x + y;
}
}
// 编译出错
Test.java:13: 错误: 已在类 Test中定义了方法 add(int,int)
public static double add(int x, int y) {
^
1 个错误
所以当两个方法的名字相同,参数也相同,但是返回值不同的时候,不构成重载。
包 (package)
为了更好地组织类,Java 提供了包机制,类似于C++中的命名空间(namespace)用于区别类名。
包的作用
- 把功能相似或相关的类或接口组织在同一个包中,方便类的查找和使用。
- 如同文件夹一样,包也采用了树形目录的存储方式。同一个包中的类名字是不同的,不同的包中的类的名字是可以相同的,当同时调用两个不同包中相同类名的类时,应该加上包名加以区别。因此,包可以避免名字冲突。
- 包也限定了访问权限,拥有包访问权限的类才能访问某个包中的类。
Java 使用包(package)这种机制是为了防止命名冲突,访问控制,提供搜索和定位类(class)、接口、枚举(enumerations)和注释(annotation)等,把不同的 java 程序分类保存,更方便的被其他 java 程序调用。 总的来说分为两大功能:提供访问保护、命名空间管理。
基本语法
包语句的语法格式为:
package pkg1[.pkg2[.pkg3…]];
例如,一个Jiedaibao.java
文件它的内容
package net.java.util;
public class Jiedaibao{
...
}
那么它的路径应该是 net/java/util/Jiedaibao.java
这样保存的。
以下是一些 Java 中的包:
java.lang
:打包基础的类java.io
:包含输入输出功能的函数
开发者可以自己把一组类和接口等打包,并定义自己的包。而且在实际开发中这样做是值得提倡的,当你自己完成类的实现之后,将相关的类分组,可以让其他的编程者更容易地确定哪些类、接口、枚举和注释等是相关的。
工程上一般使用
com.公司名.项目名.模块名.……
的形式作为包名。