Smalltalk中的自我和超级

时间:2015-09-26 19:23:11

标签: class inheritance smalltalk

我正在写Smalltalk的第一个程序。我有一个实现一个方法的超类,然后是一个继承自这个类并覆盖超​​类的子类。方法。我认为我对自我语句有困难,因为当子类调用该方法时,会调用超类和子类的平衡,以便产生累积效应,而不是 - 或选择。

这是相关代码的摘录:

Object subclass: Account [

        | balance |

        ...

        getBalance [    
            ^balance
        ]

        calculateInterest [
            balance:= (self getBalance)*0.2 + self getBalance.
        ]
    ]

Account subclass: PersonalAccount [

    ... 

    calculateInterest [ 
        super calculateInterest.
        balance := (self getBalance)*0.25 + self getBalance.
    ]
]

如何更正此问题?

2 个答案:

答案 0 :(得分:7)

所以,问题(据我所知)是,在您的实施中,PersonalAccount首先应用20%的利息(super calculateInterest),然后再增加25%,而意图是只申请25%的利息。

在不重复两个类中的代码的情况下解决此问题的最佳方法是分解interest方法,如下所示:

Account >> interest
    ^0.2

PersonalAccount >> interest
    ^0.25

现在,您可以从子类中删除calculateInterest,只留下超类中的方法

Account >> calculateInterest
    balance := self getBalance * self interest + self getBalance

这样,当#calculateInterest的接收者为Account时,余额将增加20%,而当接收者为PersonalAccount时,余额将增加25%

在旁注中,我建议将选择器getBalance替换为balance。在具有类似C语法的语言中,除了预先添加getset前缀以区分两个操作之外,别无选择。但是,在Smalltalk中,使用冒号:作为消息名称和参数之间的分隔符,使前缀的使用变得多余:您可以使用balance来读取ivar和{{1}写它。请注意,这不仅仅是为了简单起见,它还使您的代码更接近自然语言(将balance:account balance进行比较。)

答案 1 :(得分:5)

您似乎无需致电super calculateInterest

但是为了更好的设计,请考虑以下实现:

Object subclass: Account [

        | balance |

        ...

        getBalance [    
            ^balance
        ]

        getInterest [
            ^ 0.2
        ]


        calculateInterest [
            balance:= self getBalance * self getInterest + self getBalance.
        ]
    ]

Account subclass: PersonalAccount [

    ... 

    getInterest [
            ^ 0.25
   ]
]

或者您可以将兴趣作为参数,或者您可以将兴趣作为子层次的责任放在层次结构的根上,然后每个子类都应该重新定义它。

基本上你说的是:

  • 在帐户中,根据兴趣重新计算余额为“xyz”
  • 在PersonalAccount中,根据兴趣重新计算余额为:
    • 第一,基于超级课程重新计算
    • “xyz”(稍加修改)

不要以为你必须覆盖一个方法并调用super来思考你所描述的内容。