abstract class Equals<T> {
public boolean equals(T x) {
return !notEquals(x);
}
public boolean notEquals(T x) {
return !equals(x);
}
}
class Person extends Equals<Person> {
public firstname;
public lastname;
public Person(String firstname, String lastname) {
this.firstname = firstname;
this.lastname = lastname;
}
public boolean equals(Person x) {
return x.firstname == firstname &&
x.lastname == lastname;
}
}
表达式问题涉及将所有数据类型分解为可管理的部分,同时仍允许任意扩展数据类型。数据类型可以被视为一个二维矩阵,包含案例和函数。例如,考虑表达式问题是一个旧问题的新名字。目标是通过案例定义数据类型,其中可以向数据类型添加新案例和新函数,而无需重新编译现有代码,并保持静态类型安全性(例如,没有强制转换)。
Document
数据类型: Text Drawing Spreadsheet
+-----------+-----------+-----------+
draw() | | | |
+-----------+-----------+-----------+
load() | | | |
+-----------+-----------+-----------+
save() | | | |
+-----------+-----------+-----------+
public interface Document {
void draw();
void load();
void save();
}
public class TextDocument implements Document {
public void draw() { /* draw text doc... */ }
public void load() { /* load text doc... */ }
public void save() { /* save text doc... */ }
}
public class DrawingDocument implements Document {
public void draw() { /* draw drawing... */ }
public void load() { /* load drawing... */ }
public void save() { /* save drawing... */ }
}
public class SpreadsheetDocument implements Document {
public void draw() { /* draw spreadsheet... */ }
public void load() { /* load spreadsheet... */ }
public void save() { /* save spreadsheet... */ }
}
type document
= Text
| Drawing
| Spreadsheet
fun draw (Text) = (* draw text doc... *)
| draw (Drawing) = (* draw drawing doc... *)
| draw (Spreadsheet) = (* draw spreadsheet... *)
fun load (Text) = (* load text doc... *)
| load (Drawing) = (* load drawing doc... *)
| load (Spreadsheet) = (* load spreadsheet... *)
fun save (Text) = (* save text doc... *)
| save (Drawing) = (* save drawing doc... *)
| save (Spreadsheet) = (* save spreadsheet... *)
Document
数据类型切分成了九个可管理的部分。然而,我们首先按情况对数据类型进行了切分,然后将其切成了函数。因此,添加新函数很容易,但无法添加新情况。因此,该数据类型仍然不是完全可扩展的。