自引用(self reference)是一个有趣的概念,数据类型有一个自己,这个自己可以是该类型自身也可以是父类型。换言之,自引用指一个类型拥有指向该类型自身或父类型的成员变量。在本节中将讨论两个基本模型:结点/Node模型拥有一个成员变量指向本类型Node;而Num模型中NextOne拥有一个成员变量指向父类型Num。
★自引用类型有一个特征,可以编写一系列串接的new。
讨论基本模型时,模型的类体中不涉及函数,如果在这些基本模型基础上添加抽象方法,暗示会形成某种设计模式。
5.1.1 结点
5.1.2 自然数和丘奇数
教小朋友学习2的概念,可以在他面前放2个苹果,也可以敲2次铃铛。自然数,Num和ChurchNumeral两种建模方式。
自引用是一个有趣的概念,数据类型”有一个“自己。最简单的自引用,是数据结构中常用的概念——结点。然后,是自然数Num。可以定义自然数如下:自然数Num必须为Zero和NextOne。Zero是Num中最小的数,它取代结点类最后一个结点的next的值即null;而NextOne中引用父类型Num,从一个Num构造出下一个Num。
package chap5.model;
public interface Num {}
final class Zero implements Num{}
final class NextOne implements Num{
Num pre;//predecessor
NextOne(Num pre){ this.pre = pre; }
}
//class Demo
Num n = new NextOne( new NextOne( new NextOne(new Zero())));
值得注意的是,Num对象与int表示的数并非相同的数据类型。new NextOne串接3次类似于3。
如果要判断两个Num对象相等,可以改写Object .equals(Object obj)。如果在Num中定义一个int get()方法,返回本对象类似于那个int值,则NextOne需要一个静态成员变量i记录NextOne的对象创建个数;而构造一个NextOne对象,最开始都是从new Zero()开始,因此Zero的构造器将NextOne的i清零。
package chap5.model;
public interface Num{
public static Num zero = new NextOne(null);
abstract int get();
}
final class Zero implements Num {
@Override
public boolean equals(Object obj) {
return obj instanceof Zero;
}
Zero() {
NextOne.i = 0;
}
@Override
public String toString() {
return "zero";
}
@Override public int get() {
return 0;
}
}
final class NextOne implements Num {
static int i = 0;
// public static Num zero = new NextOne(null);
Num pre;//predecessor
NextOne(Num pre) {
this.pre = pre;
i+&