Subtype polymorphism 是指使用父类或接口类型来编写通用代码,而在运行时由具体子类对象决定实际执行的行为

核心思想:

  • 父类/接口定义“可以做什么“ (方法签名)
  • 子类实现“具体怎么做”(方法实现)

Comparable 可比对象

Comparable 接口对实现它的每个类为一个类定义了自然顺序排序(natural order),让他们变成天然就可以比较的对象。其中,compareTo() 方法必须(默认)被实现。

如果 this 比传入的参数大,则返回大于 0 的数,以此类推。

例如,某些对象无法被直接比较(例如通过 > 或者 <),那么就必须通过 implements comparable,并使用 compareTo 方法来进行比较。

Pasted image 20260402205128

Pasted image 20260402205216

完整实现:

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
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
public interface Comparable<T> {  
int compareTo(T o);
}

public class Dog implements Comparable<Dog> {
public String name;
private int size;

public Dog(String n, int s) {
name = n;
size = s;
}

public void bark() {
System.out.println(name + " says: bark");
}

public int compareTo(Dog uddaDog) {
return this.size - uddaDog.size;
}
}

public class Maximizer {
public static Comparable max(Comparable[] items) {
int maxDex = 0;
for (int i = 0; i < items.length; i += 1) {
int cmp = items[i].compareTo(items[maxDex]);

if (cmp > 0) {
maxDex = i;
}
}
return items[maxDex];
}
}

public class DogLauncher {
public static void main(String[] args) {
Dog d1 = new Dog("Elyse", 3);
Dog d2 = new Dog("Sture", 9);
Dog d3 = new Dog("Benjamin", 15);
Dog[] dogs = new Dog[]{d1, d2, d3};

Dog d = (Dog) Maximizer.max(dogs);
System.out.println(d.name);
}
}

并且,由于子类型多态,现在任何实现了 Comparable 的类型都可以通过 compareTo() 进行比较,并且都可以统一使用 max 这个通用的函数。


Comparator 比较器

每个类的自然排序的定义方式可能不一样,例如 Dog 是根据 size 进行排序,其他事物可能根据首字母来排序。

为了实现不同的排序方法,我们在 Java 中使用 Comparator 接口。其中包含一个必须实现的 compare() 方法,它的规则与 compareTo() 方法本质上相同。

如果传入的参数 a 比传入的参数 b 大,则返回大于 0 的数,以此类推。

由于比较器是一个对象,我们将在类的内部编写一个实现 Comparator 接口的嵌套类,这个嵌套类实现的是具体的不同的比较排序方法。

完整实现:

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
33
34
35
36
37
38
39
import java.util.Comparator;

public interface Comparator<T> {
int compare(T o1, T o2);
}

public class Dog implements Comparable<Dog> {
... // 见上个代码完整实现
public int compareTo(Dog uddaDog) {
return this.size - uddaDog.size;
}

/* 新加的嵌套类 */
private static class NameComparator implements Comparator<Dog> {
public int compare(Dog a, Dog b) {
return a.name.compareTo(b.name);
}
}

/* 为符合某种惯例,比较器本身需要设置为 private,并同时定义一个 public 的“替身” */
public static Comparator<Dog> getNameComparator() {
return new NameComparator();
}
}

public class DogLauncher {
public static void main(String[] args) {
Dog d1 = new Dog("Elyse", 3);
Dog d2 = new Dog("Sture", 9);
Dog d3 = new Dog("Benjamin", 15);

Comparator<Dog> nc = Dog.getNameComparator();
if (nc.compare(d1, d3) > 0) {
d1.bark();
} else {
d3.bark();
}
}
}

Comparable 和 Comparator 的区别:

  • Comparable 是将自身和某个东西比较
  • Comparator 是将某个东西和某个东西比较

课程中 Comparator 的应用在 Project1 的 MaxArrayDeque.java