Extending another class
Consider the method convertToNumber:. This method takes a string as an argument, and answers an integer or a float. This method really adds behavior to a String, so you can move it to the String class as follows:
1. In the Applications Browser, select Add > Extension from the Classes menu.
2. Type in String as the class to extend, and select OK.
3. Notice that String shows up in the classes pane, along with its superclasses. The grey text for each superclass indicates that those classes are not available to STCalculatorApp to add methods; you must extend those classes specifically.
4. From the classes pane select the STCalculator class. Select Not Categorized from the categories pane, and select the method convertToNumber:.
5. From the Methods menu, select Move > To A New Class.
6. In the displayed dialog, enter String.
7. In the displayed dialog, select STCalculatorApp (or the name of your application.) Dismiss the dialog with OK. Notice that convertToNumber: is now in the Not categorized category of String.
8. You will have to change the method slightly, to allow it to work on the receiver instead of the argument. Basically aString is changed to self. and the message is convertToNumber rather than convertToNumber:. Change the code to look like this (the changes are pointed out in bold):
convertToNumber
"Convert the receiver to a number. Answer either an
Integer or a Float."
| subStrings whole decimal exponent |
subStrings := self subStrings: $. .
whole := (subStrings at: 1) asNumber.
subStrings size = 1
ifTrue: [ ^whole ]
ifFalse: [
decimal := subStrings at: 2.
(decimal includes: $e)
ifTrue: [
subStrings := decimal subStrings: $e.
exponent := (subStrings at: 2) asNumber.
decimal := subStrings at: 1]
ifFalse: [
exponent := 0 ].
^(whole +
(decimal asNumber /
(10 raisedTo: (decimal size))))
* (10 raisedTo: exponent) asFloat ].
9. Save the method. You have now extended the String class by adding new behavior. This new behavior allows an instance of String to convert itself to an integer or a float.
You can delete the convertToNumber: method in the String class. Select convertToNumber: (rightmost) methods pane and use the Delete item in the popup menu.
Now let's use the new String method convertToNumber that you just added:
1. Go back to STCalculator.
2. Select the method calculateAnswer. Change the method to look like the following (the changes are pointed out in bold):
calculateAnswer: aFunction
"Private - Calculate the answer based on lastValue, aFunction,
and the current value. Answer a String."
| answer last current realFunction |
last := lastValue convertToNumber.
current := textWidget value convertToNumber.
aFunction = '='
ifTrue: [ realFunction := operation ]
ifFalse: [ realFunction := aFunction ].
state = #equals
ifTrue: [
answer := current
perform: (realFunction asSymbol)
with: last ]
ifFalse: [
answer := last
perform: (realFunction asSymbol)
with: current ].
answer class = Fraction
ifTrue: answer := answer asFloat ].
^answer printString
3. Save the method.
Let's summarize what you just did. You just gave instances of the String class the ability to convert themselves to numbers. You did that by extending the String class with the method convertToNumber. Why did you move this method to the String class? Because the method convertToNumber is a behavior you might expect strings to have. Thus, it seems that the String class would be a good place to define the behavior.
Last modified date: 06/27/2019