Shared class members
As the term "object-oriented programming" suggests, most code tends to be associated with objects, that is, instances of a class. However, it is also quite common to have class variables or methods that are independent of a specific instance of a class. For example, a class variable may contain the maximum valid value for some other class variable. Or a function may return a "work" instance of the class, instantiating a new one as needed. These members of a class are called shared members of the class in SOUL, and they are declared in Private Shared and Public Shared blocks.
Most other object-oriented languages have the same concept as shared class members, though in some of these other languages these members are called static members because:
- These variables are shared among all instances of a class and so have only one instance in the whole program.
- They are usually allocated statically in memory (as is the case with shared variables in SOUL).
The following illustrates the use of a shared variable called
that holds the highest value for another class variable called
class dog public property score is float end public private variable varScore is float end private public shared variable maxScore is float end public shared property score is float get return %varScore end get set %varScore = %score if %score gt %maxScore then %maxScore = %score end if end set end property end class
As with instance-specific variables, the shared variable
be accessed via an object variable of the class:
%competitor is object dog ... print %competitor:maxScore
Being a shared variable, however, the specific object used to access the shared variable is irrelevant, so it doesn't even matter if the object used to access the shared variable is null. Shared variables can also be accessed by using the class name enclosed in parentheses as a variable name rather than an actual object variable:
If access to shared variables via the class name is a common practice, it might be useful to allocate a "dummy" object variable with the same name as the class and to use that to reference shared variables:
%dog is object dog ... print %dog:maxScore
This is no different from accessing the shared variable via the class name in parentheses but might be viewed as aesthetically more appealing. Making this approach a standard, however, entails the requirement that when a new class is introduced, not only does the class name need to be unique among class names but also among local and common variables used anywhere the class might be used.
The term "shared method" is something of a misnomer (as is the term "static method" used in other object-oriented languages) — the code of all methods is shared among all instances of a class. What distinguishes a shared method is that a shared method does not operate on an instance of the class but instead operates independent of any instances.
For example, in the following class definition, shared method
calculates the total price of all items on a chain of items:
class purchase private variable itemNumber is fixed variable itemName is string len 32 variable next is object purchase variable quantity is fixed variable price is float ... end private private shared variable first is object purchase end private shared public shared function totalPrice is float end public shared function totalPrice is float %current is object purchase %total is float %current = %first repeat while %current ne null %total = %total + %current:price * %current:quantity %current = %current:next end repeat return %total end function end class
In a shared method, the variable %this is not defined because there is no current object instance, and non-shared variables and methods cannot be accessed without an object variable. Shared variables (in this example,
%first), however, can be accessed without any extra qualification.
The This keyword can be used to indicate the current class for shared member references inside the class. For example, in the following, the word
Thisinside parentheses means the current class, that is, class
class foo public subroutine increment end public public shared variable counter is float end public subroutine increment %(this):counter = %(this):counter + 1 end subroutine end class
While, in his example,
%(this):countercould have been written as simply
%counter, you might want to use the former syntax to highlight the fact that
Counteris a shared member of the current class.
Unlike non-shared variables, shared variables can be Static or Global. Shared Static variables are a useful place to keep class-wide constants.
While both of the examples in this section demonstrated public shared members, shared members can also be private. Shared private variables must, of course, be declared in a Private Shared block.