The following is a guest post by James Vanneman and originally appeared on his blog. James is currently a student a The Flatiron School. You can learn more about him here, or follow him on twitter here.
If you want data that only a class and it’s instances have access to, class variables often seem like the best option. Constants don’t really fit the bill because they’re accessible outside of the class and instance variables don’t work because they’re not accessible to anyone other than that specific instance. If for example, you wanted to keep track of the number of number of bank accounts your bank has you might have a class that looks like this:
So everytime a new bank account is created, the class variable @@total_accounts
increases by one and you can find the total by calling BankAccount.total_accounts
. Easy enough.
Now say we develope our software a little further and add a new class BusinessAccount
that inherits from BankAccount
. If you want to keep track of the number of business accounts your system has, you might be tempted to do something like this.
However now we run into a problem. Since class variables are shared among subclasses, setting @@total_accounts
reassigns the variable to 0.
There are two solutions to this problem. You can either namespace all of your class variables so in your BusinessAccount
class you use @@total_business_accounts
. This ends up becoming a little cumbersome, you end up with long variable names a lot of repeated code. A better solution is to use class instance variables. Refactoring the above code to use class instance variables looks like this.
Since BusinessAccount
Inherits from BankAccount
, it gets all of the methods for keeping track of the number of accounts created. The big advantage here lies in the difference between scope of class variables and instance variables. Since instance variables aren’t shared between objects they’re confined to their respective classes and keep count independently. A big win by both using less code and avoiding mixing variables unintentionally.