Chapter:Classes - Static members

From Juneday education
Jump to: navigation, search

Meta information about this chapter

Expand using link to the right to see the full content.

Introduction

The lectures in this chapter of the course material introduces static members (static variables and static methods), in the suite of chapters about classes.

Purpose

The purpose of the lectures in this chapter, is to teach the students about static members, what characterizes them, what sets them apart from instance members and when to use them. This naturally includes the keyword static and the syntax of declaring e.g. global constants, class variables and static methods.

Goal

After this chapter, the student shall understand:

  • The difference between an instance variable and a static variable
  • The difference between an instance method and a static method
  • That you can call a static method or variable for "class method" and "class variable" respectively
  • What a global constant is and how to declare one
  • What data a static method can operate on
  • Why a static method can't access an instance variable
  • The meaning and use for import static
  • Why the methods in java.lang.Math are static
  • Why the main method is static
  • How to call a static method (via the class name) from a different class
  • How to access a static variable from a different class (if access level permits it)

Instructions to the teacher

Common problems

In order to keep an object oriented focus, we purposefully introduced instance variables, constructors and instance methods before moving on to the static stuff. We've got nothing against static members, but we think we should be careful to let them take over when an object oriented solution is to be preferred. Static methods, for instance, have their uses for utility methods which are independent of state. The obvious example are the mathematical functions (the static methods in java.lang.Math. Calculating the absolute value of an integer doesn't involve state, obviously. The static methods in Math are like functions. You provide a value (or values) and they produce a result. For the same input, the output is always the same. Contrast that with the effect of calling an instance method balance() of an Account instance. The result depends on the state of the object.

A great way to test whether the students have understood static members, is to ask the students whether a static method can use an instance variable of the same class, and why not (if the students answers correctly).

Sometimes when students don't understand the use and meaning of static, it is actually an indication of a deeper misunderstanding of variables and methods in general. If a student shows signs of not understanding e.g. what a static method is and its implications, ask the student about instance methods. Can the student give an example of a typical instance method? Why is that method an instance method? What data can the instance method operate on? If the student can't give a good example or explanation of instance methods, then ask the student to revisit the lectures and exercises about instance methods before continuing with static methods and variables. Since our course material has the video lectures, taking a lecture again is no problem for the student. Remind the student to also do the exercises again, since only attending a lecture (or watching it on video) probably isn't enough in order to get a deeper understanding of programming. Practice is necessary.

When you are convinced that students understand instances, instance variables and instance methods, try again with examples of static variables and static methods, and stress the differences between them and their instance cousins.

Use examples from the Java API. Discuss them with the students. Why can't we create an instance of class Math? What about two instances? What would set two instances of Math (if we indeed could create instances of that class, which we can't) apart? Would two Math objects (if we could create such objects) have different values for PI? Of course not. There is "only one PI" constant, so it is a static final variable. Would calling Math.sqrt(9.0) ever return anything else than 3.0? Of course not. So it is a static method.

Why can't we create instances of the System class? What is the purpose of the System class? What does it contain? Take the static public out member, for instance. It represents the standard out stream. What would it mean to have several standard out streams? We only need one! Take the method public static String getenv(String name) of the System class as another example. It can be used to get the value of an environment variable. An environment variable is a rather singular thing. We don't have two PATH variables, of course! So, even if it were possible to instantiate the System class (which it isn't), calling getenv("PATH") would return the same value for any of them. Hence, it would not make sense to make this method an instance method - it is not depending on any particular instance (disregarding for the sake of the argument that we can't create instances of the System class).

We've found using examples from the Java API very useful for the students. In many occasions, they have used the example from API and therefore have an intuitive idea of how it works. And many times, it is hard to come up with better examples yourself than those present in the API. The API designers were not amateurs (even if there are a few weird things in there).

Finally, the lectures in this chapter don't bring up static initializers (they are mentioned in later lectures however). We didn't see any point in bringing them up at this point.

Classes: Static variables and methods

So far, we have focused on instance variables, i.e. variables which every instance hold their own copy of. Now it's time to introduce variables that rather belong to the class itself and that every instance of the class "share". Such variables are called "class variables" or "static variables". The latter name comes from the fact that we use the modifier static when we declare such variables.

If you think about it, there are values which are not unique to every instance of a class, but rather shared. One example would be the interest rate of a bank account of some type. It is common that every bank account of the same type (e.g. a savings account) have the same interest rate. If every savings account have the same interest rate, say 0,01%, and if this interest rate would change for every bank account, should the bank decide to change it, then it is practical to have a mechanism for expressing that the variable holding the current interest rate is shared between all instances of the class SavingsAccount.

The modifier static has precisely this meaning when applied to a variable declared in the block of a class. An example with the interest rate could look something like:

public class SavingsAccount{
  private static double interestRate = 0.01; // percent, shared by all instances
  // instance variable declarations like balance etc...
  // constructors...
  // methods...
}

An indication that a variable should be static is that the variable holds some value which is relevant to talk about without any relation to specific instances of the class. Another indication is that it is safe and natural that the variable has the same impact on every instance of a class, in the sense that if the variable's value changes, every instance will be effected by the change.

If you compare this to an instance variable such as the balance for an instance of SavingsAccount, you will see that the opposite holds for instance variables. It is not desirable that when one instance of a bank account changes the amount of the balance, every other instance of a bank account should also be affected. And it is not relevant to talk about the balance without the context of a particular instance of a bank account. The balance is the balance of one particular bank account! Therefore the balance is an instance variable which every bank account object will have its own copy of (so that they can have different balance). But the interest rate of some class of bank account, like a SavingsAccount, is relevant to talk about, even before any accounts have been created (the first customer enters the bank and decides she wants a savings account, because she agrees with the interest rate).

What about static methods, then (aka class methods)? Like with static variables, a static method is declared using the modifier static, and like static variables, static methods exist independent of any instances of the class it belongs to. Going back to the SavingsAccount class, there could be a static method for changing the static variable interestRate, something like this:

public class SavingsAccount{
  private static double interestRate = 0.01; // percent
  public static void changeInterestRate(double newRate){
    // Some logic to check that it is a feasible value...
    interestRate = newRate;
  }
  // instance variables...
  // constructors...
  // instance methods...
}

Another potential case for static methods are convenience methods which only calculate something from its parameters, like the many static methods declared in java.lang.Math, for instance public double sqrt(double d) which calculate the square root of its parameter (given as argument in the calling code). Such a method only operates on its parameters and can therefore exist totally independent of any instances. In fact, you cannot create instances of the class Math!

So how do we call a public static method? We use the class name (where the method is declared) and a dot followed by the method and arguments:

  /*
  
   |\
 A | \ C
   |__\
     B
  
  Calculate the length of C when we know the lengths of
  A (4)
  B (3)
  */
  double a = 4.0;
  double b = 3.0;
  double c = Math.sqrt(a*a+b*b); // Pythagoras...

A class method, or as it's also called, a static method, can only operate on static variables and its parameters. Why? Because we can call it regardless of any instances, even before any instances of the class is constructed. It is not possible to use instance variables inside a static method, because we don't know if there is any instances or which instance they would belong to. This is because we can call a static method via the class name so there is no reference to any specific instance known to the method.

While instance methods always have the keyword this as a reference to the instance for which the instance method was called, there is no such thing for a static method, since they are called using the class name.

Chapters about classes

Here are the chapters about classes in this book, so that you can keep a check on your progress:

Videos

Links

Further reading

Where to go next

Next page has exercises for this chapter: Classes_-_Static_members_-_Exercises

« PreviousBook TOCNext »