方法
-
定义:是一组为了实现特定功能的代码块的集合。
-
功能:
1、 结构化代码
将代码按照功能进行组织,使代码的结构比较清晰,容易阅读和修改,即程序的可维护性强。
2、减少代码重复
一个特定的功能,可能会在程序中多次使用,在使用时只需要调用写好的方法,而不用重复书写对应的功能代码。
3、访问类中私有成员
修改、查看类中的私有成员都需要类中的方法来实现,这样可以保证累得封装性良好。 -
定义方法
修饰符 方法返回类型 方法名(方法参数列表) {
若干方法语句;
return 方法返回值;
}
方法返回值通过
return
语句实现,如果没有返回值,返回类型设置为void
,可以省略return
。
- private方法
private
方法不允许外部调用,和private
字段一样,我们定义private
方法主要是用来内部调用private
方法。例如:
public class Main {
public static void main(String[] args) {
Person hong = new Person();
hong.setBirth(1999);
System.out.println(hong.getAge());
}
}
class Person {
private String name;
private int birth;
public void setBirth(int a){
this.birth=a;
}
public int getAge() {
return calcAge(2020); //调用private方法
}
//private方法
private int calcAge(int currentYear){
return currentYear-this.birth;
}
}
观察上述代码,
calcAge()
是一个private
方法,外部代码无法调用,但是,内部方法getAge()
可以调用。
这个Person
类只定义了birth
字段,没有定义age
字段,获取age
时,是通过方法getAge()
返回的一个实时计算的只,并非存储在某个字段的值。这说明了方法可以封装一个类的对外接口,用户不需要知道Person
实例在内部是否有age
字段。
- this变量
this
是存在方法内部的一个隐含变量,它始终指向当前实例。因此,通过this.field
就可以直接访问当前实例的字段。
如果没有命名冲突,可以直接省略
this
。例如:
class Person {
private String name;
public void setName(String na){
name=na; //相当于this.name=na;
}
public String getName(){
return name; //相当于this.name
}
}
如果有局部变量和字段重名,那么局部变量的优先级更高,就必须加上
this
。例如:
class Person {
private String name;
public void setName(String name){
name=name; //必须用this调用字段,不然name就成局部变量了
}
}
-
方法参数
方法可以包含0或任意数个参数。方法参数用于接受传送给方法的变量值。调用方法时必须严格按照参数的定义一一传递。 -
可变参数
可变参数用类型...
定义,可变参数相当于数组类型:
public class Main {
public static void main(String[] args) {
Person hong = new Person();
hong.setName("aaa","bbb","ccc","ddd","eee");
hong.printName();
hong.setName("aaa","bbb","ccc","ddd");
hong.printName();
hong.setName("aaa","bbb","ccc");
hong.printName();
hong.setName("aaa","bbb");
}
}
class Person {
private String []name;
public void setName(String ...names){
name=names;
}
public void printName(){
System.out.println("=======");
for(String na:name)
System.out.println(na);
}
}
其中setName()
方法也可以这么写,即将可变参数改写成String[]
类型:
public void setName(String []names){
name=names;
}
但是,用户需要自己先构造String[]
,比较麻烦。例如:
hong.setName(new String []{"aaa","bbb","ccc","ddd","eee"});//传入一个String[]
如果采用
String[]
方法传参数,用户是可以传入null
的,例如hong.setName(null);
,而可变参数可以保证无法传入null
,因为传入0个参数时,接收到的实际上是一个空数组而不是null
。
- 参数绑定
定义:调用方把参数传递给实例方法是,调用时传递的值会按照参数的位置一一绑定。下面将通过3个例子来说明参数绑定的问题。
- 基本类型参数绑定
public class Main {
public static void main(String[] args) {
Person hong = new Person();
int age=30;
hong.setAge(age);
System.out.println(hong.getAge());
age=25;
System.out.println(hong.getAge());
}
}
class Person {
private int age;
public void setAge(int a) {
age = a;
}
public int getAge() {
return age;
}
}
输出:
30
30
结论:基本类型参数的传递,是调用方值的复制。双方各自的后续修改,互不影响。
2、引用类型参数绑定(1)
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Person hong = new Person();
String[] Name=new String[]{"aaa","bbb"};
hong.setName(Name);
System.out.println(hong.getName());
Name[0]="ccc";
System.out.println(hong.getName());
}
}
class Person {
private String []name;
public String getName(){
return this.name[0]+" "+this.name[1];
}
public void setName(String[] name) {
this.name = name;
}
}
输出:
aaa bbb
ccc bbb
分析:setName()
的参数是一个数组,一开始,把Name
数组传进去,赋给Person
类中的name
数组,然后在主函数里修改Name
数组的内容,结果发现类中name
数组的内容也被修改了。
结论:引用类型参数的传递,调用方的变量和接收方的参数变量,指向的是同一个对象。双方任意一方对这个对象的修改,都会影响对方(因为调用的是同一个对象)。
3、引用类型参数绑定(2)
public class Main {
public static void main(String[] args) {
Person hong = new Person();
String na="aaa";
hong.setName(na);
System.out.println(hong.getName());
na="ccc";
System.out.println(hong.getName());
}
}
class Person {
private String name;
public String getName(){
return this.name;
}
public void setName(String name) {
this.name = name;
}
}
输出:
aaa
aaa
结论:一开始na
指向字符串aaa
,然后调用setName()
方法,使得类中的name
也指向aaa
这个字符串,然后na
又指向ccc
,相当于是放弃原先的指向,指向新开辟的一段用来存储ccc
的内存,原aaa
在内存中不变,所以类中name
字段的指向也没有发生变化,所以对na
的改动不影响name
。