Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Self and super in Smalltalk

I am writing my first program in Smalltalk. I have a super class that implements a method, and then a sub class that inherits from this class and overrides the super class' method. I am having difficulties with the self statements, I think, because when the sub class calls the method, the balance of both that of the super class and the sub class is called, so that there is an accumulative effect, rather than an either-or choice.

This is an extract of the code in question:

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.
    ]
]

How can I correct this problem?

like image 374
cadebe Avatar asked Dec 14 '22 11:12

cadebe


1 Answers

So, the problem (as I understand it) is that with your implementation the PersonalAccount applies first an interest of 20% (in super calculateInterest) and then an additional 25%, while the intention is to only apply an interest of 25%.

The best way to address this without repeating code in both classes is to factor out the interest method, like this:

Account >> interest
    ^0.2

PersonalAccount >> interest
    ^0.25

Now, you can remove calculateInterest from the subclass and leave only the method in the superclass

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

In this way, when the receiver of #calculateInterest is an Account the balance will be increased in 20%, and when the receiver is a PersonalAccount, the balance will increase 25%.

On a side note, I would recommend replacing the selector getBalance with balance. In languages with a C-like syntax, there is no option but to prepend get and set prefixes to differentiate between two actions. In Smalltalk, however, the use of colon : as the separator between the message name and the argument, makes it superfluous the use of prefixes: you can use balance to read the ivar and balance: to write it. Note that this is no just for the sake of simplicity, it also makes your code closer to the natural language (compare account balance with account getBalance.)

like image 170
Leandro Caniglia Avatar answered Jan 04 '23 09:01

Leandro Caniglia