10. Oh My!¶
tags: | java, oop |
---|---|
category: | java |
Contents
abstract class FruitD {} // 水果
class Peach extends FruitD { //桃
public boolean equals(Object o) {
return (o instanceof Peach);
}
}
class Apple extends FruitD { //苹果
public boolean equals(Object o) {
return (o instanceof Apple);
}
}
class Pear extends FruitD { //梨
public boolean equals(Object o) {
return (o instanceof Pear);
}
}
class Lemon extends FruitD { //柠檬
public boolean equals(Object o) {
return (o instanceof Lemon);
}
}
class Fig extends FruitD { //无花果
public boolean equals(Object o) {
return (o instanceof Fig);
}
}
abstract class TreeD { //树
abstract boolean accept(bTreeVisitorI ask);
abstract int accept(iTreeVisitorI ask);
abstract TreeD accept(tTreeVisitorI ask);
}
class Bud extends TreeD { //芽
boolean accept(bTreeVisitorI ask) {
return ask.forBud();
}
int accept(iTreeVisitorI ask) {
return ask.forBud();
}
TreeD accept(tTreeVisitorI ask) {
return ask.forBud();
}
}
class Flat extends TreeD { //平顶
FruitD f;
TreeD t;
Flat(FruitD _f, TreeD _t) {
f = _f;
t = _t;
}
boolean accept(bTreeVisitorI ask) {
return ask.forFlat(f, t);
}
int accept(iTreeVisitorI ask) {
return ask.forFlat(f, t);
}
TreeD accept(tTreeVisitorI ask) {
return ask.forFlat(f, t);
}
}
class Split extends TreeD { //分枝
TreeD l;
TreeD r;
Split(Treed _l, TreeD _r) {
l = _l;
r = _r;
}
boolean accept(bTreeVisitorI ask) {
return ask.forSplit(l, r);
}
int accept(iTreeVisitorI ask) {
return ask.forSplit(l, r);
}
TreeD accept(tTreeVisitorI ask) {
return ask.forFlat(l, r);
}
}
interface bTreeVisitorI {
boolean forBud();
boolean forFlat(FruitD f, TreeD t);
boolean forSplit(TreeD l, TreeD r);
}
class bIsFlatV implements bTreeVisitorI {
public boolean forBud() {
return true;
}
public boolean forFlat(FruitD f, TreeD t) {
return t.accept(this);
}
public boolean forSplit(TreeD l, TreeD r) {
return false;
}
}
class bIsSplitV implements bTreeVisitorI {
public boolean forBud() {
return true;
}
public boolean forFlat(FruitD f, TreeD t) {
return false;
}
public boolean forSplit(TreeD l, TreeD r) {
return l.accept(this) && r.accept(this);
}
}
class bHasFruitV implements bTreeVisitorI {
public boolean forBud() {
return false;
}
public boolean forFlat(FruitD f, TreeD t) {
return true;
}
public boolean forSplit(TreeD l, TreeD r) {
return l.accept(this) || r.accept(this);
}
}
interface iTreeVisitorI {
int forBud();
int forFlat(FruitD f, TreeD t);
int forSplit(TreeD l, TreeD r);
}
class iHeightV implements iTreeVisitorI {
public int forBud() {
return 0;
}
public int forFlat(FruitD f, TreeD t) {
return t.accept(this) + 1;
}
public int forSplit(TreeD l, TreeD r) {
return (l.accept(this) |_| r.accept(this)) + 1;
}
}
class iOccursV implements iTreeVisitorI {
FruitD a;
iOccursV(FruitD _a) {
a = _a;
}
public int forBud() {
return 0;
}
public int forFlat(FruitD f, TreeD t) {
if (f.equals(a))
return t.accept(this) + 1;
else
return t.accept(this);
}
public int forSplit(TreeD l, TreeD r) {
return l.accept(this) + r.accept(this);
}
}
interface tTreeVisitorI {
TreeD forBud();
TreeD forFlat(FruitD f, TreeD t);
TreeD forSplit(TreeD l, TreeD r);
}
class tSubstV implements tTreeVisitorI {
FruitD n;
FruitD o;
tSubstV(FruitD _n, FruitD _o) {
n = _n;
o = _o;
}
public TreeD forBud() {
return new Bud();
}
public TreeD forFlat(FruitD f, TreeD t) {
if (o.equals(f))
return new Flat(n, t.accept(this));
else
return new Flat(f, t.accept(this));
}
public TreeD forSplit(TreeD l, TreeD r) {
return new Split(l.accept(this), r.accept(this));
}
}
上面的三个接口是不是有点繁琐?那么将它合并起来。
interface TreeVisitorI {
Object forBud();
Object forFlat(FruitD f, TreeD t);
Object forSplit(TreeD l, TreeD r);
}
abstract class TreeD {
abstract Object accept(TreeVisitorI ask);
}
class Bud extends TreeD {
Object accept(TreeVisitorI ask) {
return ask.forBud();
}
}
class Flat extends TreeD {
FruitD f;
TreeD t;
Flat(FruitD _f, TreeD _t) {
f = _f;
t = _t;
}
Object accept(TreeVisitorI ask) {
return ask.forFlat(f, t);
}
}
class Split extends TreeD {
TreeD l;
TreeD r;
Split(Treed _l, TreeD _r) {
l = _l;
r = _r;
}
Object accept(TreeVisitorI ask) {
return ask.forSplit(l, r);
}
}
class IsFlatV implements TreeVisitorI {
public Object forBud() {
return new Boolean(true);
}
public Object forFlat(FruitD f, TreeD t) {
return t.accept(this);
}
public Object forSplit(TreeD l, TreeD r) {
return new Boolean(false);
}
}
class bIsSplitV implements bTreeVisitorI {
public boolean forBud() {
return new Boolean(true);
}
public boolean forFlat(FruitD f, TreeD t) {
return new Boolean(false);
}
public boolean forSplit(TreeD l, TreeD r) {
if (((Boolean)(l.accept(this))).booleanValue())
return r.accept(this);
else:
return new Boolean(false);
}
}
小技巧
第七条建议
When designing visitor protocols for
many different types, create a unifying
protocol using Object .
但是这有一个不好的地方,如果返回的是Java的内置类型,
那内部在进行处理时,就要先进行转换,有时候甚至要令人发指的程度。
比如下面的代码:
class OccursV implements TreeVisitorI {
FruitD a;
iOccursV(FruitD _a) {
a = _a;
}
public Object forBud() {
return new Integer(0);
}
public Object forFlat(FruitD f, TreeD t) {
if (f.equals(a))
return new Integer(((Integer)(t.accept(this))).intValue() + 1);
else
return t.accept(this);
}
public int forSplit(TreeD l, TreeD r) {
return new Integer(((Integer)(l.accept(this))).intValue()
+
((Integer)(r.accept(this))).intValue());
}
}
小技巧
难道只能这样?下面的章节给你答案。