一、方法

方法类似 c++ 中的函数概念。
image.png

1.1 实现方法

封装是面向对象的一个基本特性,可以隐藏信息。将字段的访问设为 private 私有的,就可以拒绝外部的访问。

  1. class Person {
  2. private String name;
  3. private int age;
  4. }

通过方法来对字段进行设置值和获取值的操作。

  1. public class Main {
  2. public static void main(String[] args) {
  3. Person ming = new Person();
  4. ming.setName("Xiao Ming"); // 设置name
  5. ming.setAge(12); // 设置age
  6. System.out.println(ming.getName() + ", " + ming.getAge());
  7. }
  8. }
  9. class Person {
  10. private String name;
  11. private int age;
  12. public String getName() {
  13. return this.name;
  14. }
  15. public void setName(String name) {
  16. this.name = name;
  17. }
  18. public int getAge() {
  19. return this.age;
  20. }
  21. public void setAge(int age) {
  22. if (age < 0 || age > 100) {
  23. throw new IllegalArgumentException("invalid age value");
  24. }
  25. this.age = age;
  26. }
  27. }

在方法内部,可以设置值的范围,比如 setAge() 方法。
一个类通过定义方法,就可以给外部代码暴露一些操作的接口。

1.2 private 方法

  1. public class learn1 {
  2. public static void main(String[] args) {
  3. Person ming = new Person();
  4. ming.setBirth(2008);
  5. // ming.calcAge(2019); // 不可以 java: calcAge(int) 在 Person 中是 private 访问控制
  6. System.out.println(ming.getAge());
  7. }
  8. }
  9. class Person {
  10. private String name;
  11. private int birth;
  12. public void setBirth(int birth) {
  13. this.birth = birth;
  14. }
  15. public int getAge() {
  16. return calcAge(2019); // 调用private方法
  17. }
  18. // private方法:
  19. private int calcAge(int currentYear) {
  20. return currentYear - this.birth;
  21. }
  22. }

第 5 行 java: calcAge(int)Person 中是 private 访问控制,外部不可以直接调用。

这边 getAge() 方法获取 age,不用管 Person 内部到底有没有 age 字段,那是类的具体实现细节,封装就是会隐藏,调用方只管接口就好。

二、方法的参数

2.1 普通参数

普通参数有 0 个或 n 个,按照顺序和类型一一传递就好。

2.2 可变参数

可变参数相当于数组类型

  1. class Group {
  2. private String[] names;
  3. public void setNames(String... names) {
  4. this.names = names;
  5. }
  6. }
  7. Group g = new Group();
  8. g.setNames("Xiao Ming", "Xiao Hong", "Xiao Jun"); // 传入3个String
  9. g.setNames("Xiao Ming", "Xiao Hong"); // 传入2个String
  10. g.setNames("Xiao Ming"); // 传入1个String
  11. g.setNames(); // 传入0个String

三、参数绑定

3.1 基本类型参数传递

  1. public class Main {
  2. public static void main(String[] args) {
  3. Person p = new Person();
  4. int n = 15; // n的值为15
  5. p.setAge(n); // 传入n的值
  6. System.out.println(p.getAge()); // 15
  7. n = 20; // n的值改为20
  8. System.out.println(p.getAge()); // 15
  9. }
  10. }
  11. class Person {
  12. private int age;
  13. public int getAge() {
  14. return this.age;
  15. }
  16. public void setAge(int age) {
  17. this.age = age;
  18. }
  19. }

n 是一个外部的局部变量,getAge() 获取的是对象的 age,不是同一个数据。

3.2 引用参数传递

java 数组作为方法的参数时,传递的是地址。因此是会指向同一个位置。

  1. public class Main {
  2. public static void main(String[] args) {
  3. Person p = new Person();
  4. String[] fullname = new String[] { "Homer", "Simpson" };
  5. p.setName(fullname); // 传入fullname数组
  6. System.out.println(p.getName()); // "Homer Simpson"
  7. fullname[0] = "Bart"; // fullname数组的第一个元素修改为"Bart"
  8. System.out.println(p.getName()); // 输出 Bart Simpson"
  9. }
  10. }
  11. class Person {
  12. private String[] name;
  13. public String getName() {
  14. return this.name[0] + " " + this.name[1];
  15. }
  16. public void setName(String[] name) {
  17. this.name = name;
  18. }
  19. }