方法就是将一个功能抽取出来,把代码单独定义在一个大括号内,形成一个单独的功能。 当需要这个功能的时候,就可以去调用。这样即实现了代码的复用性,也解决了代码冗余的现象。
修饰符 返回值类型 方法名 (参数列表){
代码...
return 返回值;
}
定义格式解释:
方法必须定义在一类中方法外,不能定义在另一个方法的里面,定义方法需明确返回值类型和参数列表,返回值类型,必须要和 return 语句返回的类型相同,否则编译失败。不能在 return 后面写代码, return 意味着方法结束,所有后面的代码永远不会执行,属于无效代码。
方法定义时的参数叫形参,方法调用时的参数叫实参,实参和形参的类型要一直或兼容,个数、顺序必须一致。
方法不能嵌套定义!!
同一个类中的方法可以直接调用,跨类调用需要通过对象名调用,比如对象名.方法名(参数);
,方法的调用还和访问修饰符相关。
public class Method01 {
public static void main(String[] args) {
// 方法的使用
// 定义好方法后,如果不调用,则不会执行
// 先创建对象,然后进行调用
Person p1 = new Person();
p1.speak(); // 这里调用方法
p1.cal01();
p1.cal02(1000); // 传入的是1000,则n=1000
p1.cal02(5); // 一个对象的方法可以调用多次
// 将该方法返回的int值 赋值给 sum 变量
int sum = p1.getSum(10, 20); // 传参是10,20,则n = 10, m = 20,使用int sum来接收方法的返回值
System.out.println("getSum方法得到的返回值为:" + sum);
}
}
class Person {
String name;
int age;
// 方法(成员方法)
// 输出“我是一个好人”
// public:表示方法是公开的
// void:表示方法没有返回值
// speak:方法名
// ():形参列表
// {}:方法体,就是要执行的代码
public void speak() {
System.out.println("我是一个好人");
}
// 计算1+...+100
public void cal01() {
// 进行循环
int res = 0;
for (int i = 1; i <= 100; i++) {
res += i;
}
System.out.println("cal01计算结果:" + res);
}
// 计算1+...+n
// (int n):形参列表,表示当前方法可以传入一个int的值
public void cal02(int n) {
int res = 0;
for (int i = 1; i <= n; i++) {
res += i;
}
System.out.println("cal02计算结果:" + res);
}
// 计算两个数的和,并返回
// public后面的int:表示方法执行后,返回给调用者一个int的值
// (int n, int m):有两个形参,表示当前方法可以接收两个参数
// return res;:表示把res的值返回给调用者
public int getSum(int n, int m) {
int res = m + n;
return res;
}
}
(参考上面代码)
public class MethodParameter01 {
//编写一个 main 方法
public static void main(String[] args) {
int a = 10;
int b = 20;
//创建 AA 对象 名字obj
AA obj = new AA();
obj.swap(a, b);//调用 swap
System.out.println("\nmain 方法 a=" + a + " b=" + b);//a=10 b=20
}
}
class AA {
public void swap(int a, int b) {
System.out.println("\na 和 b 交换前的值\na=" + a + "\tb=" + b);//a=10 b=20
// 完成了 a 和 b 的交换
int tmp = a;
a = b;
b = tmp;
System.out.println("\na 和 b 交换后的值\na=" + a + "\tb=" + b);//a=20 b=10
}
}
基本数据类型传递的是值(值拷贝),形参的任何改变不影响实参
当执行obj.swap(a, b);
的时候会进入swap方法中,在该方法中,该方法的参数a和b完成了值的交换,但是main方法中的a和b并没有交换,所以输出如下:
public class MethodParameter02 {
//编写一个 main 方法
public static void main(String[] args) {
B b = new B();
int[] arr = {1, 2, 3};
b.test(arr); //调用方法
System.out.println(" main 的 arr 数组 ");
//遍历数组
for (int i = 0; i < arr.length; i++) {
System.out.print(arr[i] + "\t");
}
System.out.println();
}
}
class B {
public void test(int[] arr) {
arr[0] = 200; //修改元素
// 遍历数组
System.out.println(" test100 的 arr 数组 ");
for (int i = 0; i < arr.length; i++) {
System.out.print(arr[i] + "\t");
}
System.out.println();
}
}
引用类型传递的是地址(传递也是值,但是值是地址),可以通过形参影响实参!
java 中允许同一个类中,多个同名方法的存在,但要求形参列表不一致。只要它们的参数列表不同即可,与修饰符和返回值类型无关。 比如:System.out.println();
out 是 PrintStream 类型。
public class OverLoad01 {
public static void main(String[] args) {
MyCalculate mc = new MyCalculate();
System.out.println(mc.calculate(1, 2)); // 打印结果:3
System.out.println(mc.calculate(3, 4.5)); // 打印结果:7.5
System.out.println(mc.calculate(1.2, 2)); // 打印结果:3.2
System.out.println(mc.calculate(1, 4, 7)); // 打印结果:12
}
}
// 这个类的四个calculate方法构成了重载
// 方法名一样,参数列表的类型不一样
class MyCalculate {
// 两个整数的和
public int calculate(int n1, int n2) {
return n1 + n2;
}
// 这个方法和上面的方法不构成重载,因为参数列表的类型相同
// public int calculate(int a1, int a2) {
// return a1 + a2;
// }
// 一个整数和一个浮点数的和
public double calculate(int n1, double n2) {
return n1 + n2;
}
// 一个浮点数和一个整数的和
public double calculate(double n1, int n2) {
return n1 + n2;
}
// 三个整数的和
public int calculate(int n1, int n2, int n3) {
return n1 + n2 + n3;
}
}
Java允许将同一个类 多个同名 同功能 但 参数个数不同的方法,封装成一个方法。在JDK1.5之后,如果定义一个方法需要接收多个参数,并且多个参数类型一致,可以对其简化成如下格式:
修饰符 返回值类型 方法名(参数类型... 形参名){ }
public class ChangeParam01 {
// 计算两个数的和,三个数的和,四个数的和,五个数的和....
// 可以使用方法重载
public int sum(int n1, int n2) {return n1 + n2;}
public int sum(int n1, int n2, int n3) {return n1 + n2 + n3;}
public int sum(int n1, int n2, int n3, int n4) {return n1 + n2 + n3 + n4;}
// 上面三个方法名称相同,功能相同,只有参数个数不同,可以使用可变参数优化
// int... 表示该参数是可变参数,类型是int,可以接收多个int类型的参数(0-n个参数)
public int sums(int... nums) {
// 使用可变参数时,可以当做数组使用,所以nums是一个数组
System.out.println("接收的参数个数为:" + nums.length);
int sum = 0;
for (int i = 0; i < nums.length; i++) {
sum += nums[i];
}
return sum;
}
public static void main(String[] args) {
ChangeParam01 cp = new ChangeParam01();
int res = cp.sums(0, 1, 2, 3, 4, 5, 6, 7);
System.out.println("返回的结果为:" + res);
int[] arr = {3, 6, 9};
// 可变参数的实参可以传入数组
int res2 = cp.sums(arr);
System.out.println("res2的结果:" + res2);
}
}
public void sums(String str, double... nums) {}
在Java中,主要的变量就是成员变量和局部变量。
在同一个类中,成员变量和局部变量可以重名,访问时遵循就近原则;但是在同一个作用域中,比如在同一个成员方法中,两个局部变量不能重名。
默认值:
生命周期:
作用域:
修饰符:
构造方法又叫构造器(constructor),是类的一种特殊的方法,它的主要作用是完成对新对象的初始化。当一个对象被创建时候,构造方法用来初始化该对象,给对象的成员变量赋初始值。
[修饰符] 方法名(形参列表){
方法体;
}
package object;
public class Constructor {
public static void main(String[] args) {
// 使用两种不同的构造器
Person p = new Person("张三", 25);
System.out.println("name:" + p.name);
System.out.println("age:" + p.age);
Person p1 = new Person("李四");
System.out.println("name:" + p1.name);
System.out.println("age:" + p1.age);
}
}
class Person {
String name;
int age;
// 构造器没有返回值,也不需要写void
// 构造方法的方法名必须和类名一样
// 形参列表和其他方法一样
public Person(String pName, int pAge) {
System.out.println("构造器执行了....");
name = pName;
age = pAge;
System.out.println("构造器完成了对属性的初始化...");
}
// 构造器可以重载
public Person(String pName) {
name = pName;
}
// 如果我们定义了构造器,则默认构造器会被覆盖,如果需要,可以手动创建无参构造
// 默认的无参构造访问修饰符也是默认的
public Person() {
}
}
可以使用javap工具反编译,能看到反编译后的结果中有定了一个 访问修饰符为默认 方法名为类名的方法。
class Person {
String name;
int age = 90;
// 构造器
Person(String n, int a) {
name = n;
age = a;
}
}
// 对象创建时发生了什么
Person p = new Person("张三", 20);
Java虚拟机会给每个对象分配this, 代表所在类的当前对象的引用(地址值),即对象自己的引用。方法被哪个对象调用,方法中的this就代表那个对象。即谁在调用,this就代表谁,方法中只有一个变量名时,默认也是使用 this 修饰,可以省略不写。
class Dog {
String name;
int age;
// 不使用this,name则等于该方法中的name(就近原则)
// public Dog(String name, int age){
// name = name;
// age = age;
// }
// 使用this 相当于是Dog对象.name,指的是Dog类中的属性,而没有加this的name指的是方法中的name
public Dog(String name, int age) {
this.name = name;
this.age = age;
}
}
this关键字可以访问本类的属性、方法、构造器
this用于区分当前类的属性和局部变量
访问成员方法的语法:this.方法名(参数列表);
访问构造器语法:this(参数列表);
,只能在构造器中使用(并且必须放在第一行)
this不能再类定义的外部使用,只能在类定义的方法中使用