In the above exercise, you built a single ApplicationConfiguration
class that will serve the needs of a single application well enough. But what happens when I have multiple applications and need to store their configuration as well?
The simplest answer is to build new classes, one for each application, and have them inherit from ApplicationConfiguration
so that we get the set
and get
methods. Let us see how that works out:
I'm sure you figured out what is going on in here. Even though I have two classes, changes in one affects changes in the other. It also seems that the base class ApplicationConfiguration
too is affected when you change anything in any inherited class.
The fact is that any change in any either ApplicationConfiguration
, ERPApplicationConfiguration
or WebApplicationConfiguration
will affect the other two. They all share the same copy of the class variable @@configuration
. This is how inheritance of class variables work. But this is not the behavior we want!
The answer to this lies in another type of class variables: class instance variables.
Here is an example of defining a class instance variable and how it works with inheritance:
The class instance variable in the above example is @foo
. Even though the notation is confusingly similar to a normal instance variable, the difference here is that @foo
is initialized directly in the class body and is accessed only from class methods.
As you can see, the values for @foo_count
are different for both Foo
and Bar
. This means that both classes are operating on different @foo_count
. Note that we have to initialize @foo_count
in all inherited classes.
Now, can you fix our ApplicationConfiguration
example to work correctly for both parent and child classes?
Class instance variables are a better alternative than class variables simply because the data is not shared across the inheritance chain. Another major difference between class variables and class instance variables are that class instance variables are available only in class methods. But class variables are available in both class methods and instance methods.
A quick summary before we move on:
- Instance variables are available only for instances of a class. They look like
@name
. Class variables are available to both class methods and instance methods. They look like @@name
- It is almost always a bad idea to use a class variable to store state. There are only a very few valid use cases where class variables are the right choice.
- Prefer class instance variables over class variables when you do really need store data at a class level. Class instance variables use the same notation as that of an instance variable. But unlike instance variables, you declare them inside the class definition directly.