面向对象基础

“在面向对象中,方法是对象的行为,它们依附于对象,通过对象来调用,而不是独立存在的。”

构造方法

为了保护class中的数据,避免被直接修改,出现如超出范围之类的错误,我们可以使用private字段对属性进行限制。

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

使用private进行限制的属性,我们可以使用在同一个class中定义的方法来实现对类中private属性的变量进行控制,如

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
public class Main {
public static void main(String[] args) {
Person ming = new Person();
ming.setName("Xiao Ming"); // 设置name
ming.setAge(12); // 设置age
System.out.println(ming.getName() + ", " + ming.getAge());
}
}

class Person {
private String name;
private int age;

public String getName() {
return this.name;
}

public void setName(String name) {
this.name = name;
}

public int getAge() {
return this.age;
}

public void setAge(int age) {
if (age < 0 || age > 100) {
throw new IllegalArgumentException("invalid age value");
}
this.age = age;
}
}

同样的,一个类里面我们也可以存在private方法,这样的方法只能由类中其他方法进行调用。

this

在方法内部,隐含一个变量this,始终指向当前示例。在多数情况下,this不用显示写出。

特例:

如果局部变量和字段重名,局部变量的优先级更高,因此为了区分变量名,我们需要显式地加上this。

1
2
3
4
5
6
7
class Person {
private String name;

public void setName(String name) {
this.name = name; // 前面的this不可少,少了就变成局部变量name了
}
}

可变参数

正常使用方法参数时,我们需要准确的对应参数的类型、数量,才可以正确使用类中的方法。

1
2
3
Person ming = new Person();
ming.setNameAndAge("Xiao Ming"); // 编译错误:参数个数不对
ming.setNameAndAge(12, "Xiao Ming"); // 编译错误:参数类型不对

但是在可变参数中,我们可以批量传入一批参数。可变参数相当于数组。

1
2
3
4
5
6
7
class Group {
private String[] names; //将类中存储变量的数据类型转为数组

public void setNames(String... names) {
this.names = names;
}
}

方法2:

我们在传入参数的时候不使用多个string一起传入,而是使用一个String[]。

不过这样的做法有两个缺点:

  • 调用方需要自己构建一个String[]
  • 调用方可以传入null,而可变参数可以保证无法传入null(此时实际上是传入的空数组而不是null)

参数绑定

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
// 引用类型参数绑定
public class Main {
public static void main(String[] args) {
Person p = new Person();
String[] fullname = new String[] { "Homer", "Simpson" };
p.setName(fullname); // 传入fullname数组
System.out.println(p.getName()); // "Homer Simpson"
fullname[0] = "Bart"; // fullname数组的第一个元素修改为"Bart"
System.out.println(p.getName()); // "Homer Simpson"还是"Bart Simpson"?
}
}

class Person {
private String[] name;

public String getName() {
return this.name[0] + " " + this.name[1];
}

public void setName(String[] name) {
this.name = name;
}
}

此时传参传的是fullname[],是一个数组,具有指针的性质,因此值会随数组中内容的变化而变化。

但是需要注意在传参时,我们使用的究竟是什么。是数组中的数据还是数组本身的变量名。

(类似于c语言中,我们到底是读取的指针的地址还是指针地址对应的值)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
// 引用类型参数绑定
public class Main {
public static void main(String[] args) {
Person p = new Person();
String bob = "Bob";
p.setName(bob); // 传入bob变量
System.out.println(p.getName()); // "Bob"
bob = "Alice"; // bob改名为Alice
System.out.println(p.getName()); // "Bob"还是"Alice"?
}
}

class Person {
private String name;

public String getName() {
return this.name;
}

public void setName(String name) {
this.name = name;
}
}