January Star
  • Home
  • Categories
  • Tags
  • Archives

Like Father, Like Son

这一章节主要讲到了继承,从章节题目也可以看出来 : 父子。


 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
48
49
50
51
52
53
54
55
56
interface ExprVisitorI {
    Object forPlus(ExprD l, ExprD r); // 相加 
    Object forDiff(ExprD l, ExprD r); // 相减 
    Object forProd(ExprD l, ExprD r); // 相乘 
    Object forConst(Object c); // 常量 
}

abstract class ExprD {
    abstract Object accept(ExprVisitorI ask);
}

class Plus extends ExprD {
    ExprD l;
    ExprD r;
    Plus(ExprD _l, ExprD _r) {
        l = _l;
        r = _r;
    }
    Object accept(ExprVisitorI ask){
        return ask.forPlus(l, r);
    }
}

class Diff extends ExprD {
    ExprD l;
    ExprD r;
    Diff(ExprD _l, ExprD _r) {
        l = _l;
        r = _r;
    }
    Object accept(ExprVisitorI ask){
        return ask.forDiff(l, r);
    }
}

class Prod extends ExprD {
    ExprD l;
    ExprD r;
    Prod(ExprD _l, ExprD _r) {
        l = _l;
        r = _r;
    }
    Object accept(ExprVisitorI ask){
        return ask.forProd(l, r);
    }
}

class Const extends ExprD {
    Object c;
    Const(Object _c){
        c = _c;
    }
    Object accept(ExprVisitorI ask){
        return ask.forConst(c);
    }
}
 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
class IntEvalV implements ExprVisitorI {
    public Object forPlus(ExprD l, ExprD r){
        return plus(l.accept(this), r.accept(this));
    }
    public Object forDiff(ExprD l, ExprD r){
        return diff(l.accept(this), r.accept(this));
    }
    public Object forProd(ExprD l, ExprD r){
        return prod(l.accept(this), r.accept(this));
    }
    public Object forConst(Object c){
        return c;
    }
    Object plus(Object l, Object r){
        return new Integer(((Integer)l).intValue()
                           +
                           ((Integer)r).intValue());
    }
    Object diff(Object l, Object r){
        return new Integer(((Integer)l).intValue()
                           -
                           ((Integer)r).intValue());
    }
    Object prod(Object l, Object r){
        return new Integer(((Integer)l).intValue()
                           *
                           ((Integer)r).intValue());
    }
}
 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
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
abstract class SetD {
    SetD add(Integer i){
        if (mem(i))
            return this;
        else
            return new Add(i, this);
    }
    abstract boolean mem(Integer i);
    abstract SetD plus(SetD s);
    abstract SetD diff(SetD s);
    abstract SetD prod(SetD s);
}

class Empty extends SetD {
    boolean mem(Integer i){
        return false;
    }
    SetD plus(SetD s){
        return s;
    }
    SetD diff(SetD s){
        return new Empty();
    }
    SetD prod(SetD s){
        return new Empty();
    }
}

class Add extends SetD {
    Integer i;
    SetD s;
    Add(Integer _i, SetD _s){
        i = _i;
        s = _s;
    }
    boolean mem(Integer n){
        if (i.equals(n))
            return true;
        else
            return s.mem(n);
    }
    SetD plus(SetD t){
        return s.plus(t.add(i));
    }
    SetD diff(SetD t){
        if (t.mem(i))
            return s.diff(t);
        else
            return s.diff(t).add(i);
    }
    SetD prod(SetD t){
        if (t.mem(i))
            return s.prod(t).add(i);
        else
            return s.prod(t);
    }
}

class SetEvalV extends IntEvalV {
    Object plus(Object l, Object r){
        return ((SetD)l).plus((SetD)r);
    }
    Object diff(Object l, Object r){
        return ((SetD)l).diff((SetD)r);
    }
    Object prod(Object l, Object r){
        return ((SetD)l).prod((SetD)r);
    }
}

SetEvalV 直接继承 IntEvalV 有点不合理,好,我们改一下。

 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
abstract class EvalD implements ExprVisitorI {
    public Object forPlus(ExprD l, ExprD r){
        return plus(l.accept(this), r.accept(this));
    }
    public Object forDiff(ExprD l, ExprD r){
        return diff(l.accept(this), r.accept(this));
    }
    public Object forProd(ExprD l, ExprD r){
        return prod(l.accept(this), r.accept(this));
    }
    public Object forConst(Object c){
        return c;
    }
    abstract Object plus(Object l, Object r);
    abstract Object diff(Object l, Object r);
    abstract Object prod(Object l, Object r);
}

class IntEvalV extends EvalD {
    Object plus(Object l, Object r){
        return new Integer(((Integer)l).intValue()
                           +
                           ((Integer)r).intValue());
    }
    Object diff(Object l, Object r){
        return new Integer(((Integer)l).intValue()
                           -
                           ((Integer)r).intValue());
    }
    Object prod(Object l, Object r){
        return new Integer(((Integer)l).intValue()
                           *
                           ((Integer)r).intValue());
    }
}

class SetEvalV extends EvalD {
    Object plus(Object l, Object r){
        return ((SetD)l).plus((SetD)r);
    }
    Object diff(Object l, Object r){
        return ((SetD)l).diff((SetD)r);
    }
    Object prod(Object l, Object r){
        return ((SetD)l).prod((SetD)r);
    }
}

还记得第 6 章的 SubstV 和 LtdSubstV 么?

它们有很多相似的地方,能否合并起来?

 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
abstract class SubstD implements PieVisitorI {
    Object n;
    Object o;
    SubstD(Object _n, Object _o) {
        n = _n;
        o = _o;
    }
    public PieD forBot() {
        return new Bot();
    }
    public abstract PieD forTop(Object t, PieD r);
}

class SubstV extends SubstD {
    SbustV(Object _n, Object _o) {
        super(_n, _o);
    }
    public PieD forTop(Object t, PieD r) {
        if (o.equals(t))
            return new Top(n, r.accept(this));
        else
            return new Top(t, r.accept(this));
    }
}

class LtdSubstV extends SubstD {
    int c;
    LtdSubstV(int _c, Object _n, Object _o) {
        super(_n, _o);
        c = _c;
    }
    public PieD forTop(Object t, PieD r) {
        if (c == 0)
            return new Top(t, r);
        else
            if (o.equals(t))
                return new Top(n, r.accept(LtdSubstV(c-1, n, o)));
            else
                return new Top(t, r.accept(this));
    }
}

第八条建议

当继承某个类时,使用重载来扩展它的功能。

根据以上建议, LtdSubstV 可以直接在 SbustV 类上进行继承和扩展。

 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
class SbustV implements PieVisitorI {
    Object n;
    Object o;
    SubstV(Object _n, Object _o) {
        n = _n;
        o = _o;
    }
    public PieD forBot() {
        return new Bot();
    }
    public PieD fotTop(Object t, PieD r) {
        if (o.equals(t))
            return new Top(n, r.accept(this));
        else
            return new Top(t, r.accept(this));
    }
}

class LtdSubstV extends SubstV {
    int c;
    Object n;
    Object o;
    LtdSubstV(int _c, Object _n, Object _o) {
        super(_n, _o);
        c = _c;
    }
    public PieD forTop(Object t, PieD r) {
        if (c == 0)
            return new Top(t, r);
        else
            if (o.equals(t))
                return new Top(n, r.accept(LtdSubstV(c-1, n, o)));
            else
                return new Top(t, r.accept(this));
    }
}

不过这样一来反而违反了 里氏替换原则 ,不知道作者为什么这样写?

还是我自己太教条了,或者没有理解 里氏替换原则 。

Comments
comments powered by Disqus

Published

Sep 25, 2014

Category

java

Tags

  • java 13
  • oop 13

Contact

  • Powered by Pelican. Theme: Elegant by Talha Mansoor