Java Modifiers

This page contains course notes for Object Oriented Programming taught in the Spring of 2011. If you have come here from a search engine or the like, you may wish to visit the course home page for more material, or visit my general teaching page for possibly more up to date versions, or perhaps my home page

Plan for this lecture:

  1. Static variables
  2. Static methods
  3. final static
  4. public classes, variables, methods
  5. private classes, variables, methods
  6. protected classes?, variables, methods
  7. No modifier.
  1. Up to this point, we've made a big deal that all member fields in a class have separate copies in each instance of the class, so if we have two variables: Point one,two; then one.x is a different variable from one.y.
  2. There is an exception to this, one that is very similar to C++, if you happen to have seen it. We can declare a member field as static. In that case the variable is shared between all instances.
          class Point {
            int x,y;
            static int num;
          }
        
  3. In this case one.num is the same variable as two.num. If I change one.num, I change two.num as well. Try it.
  4. This is handy for information that should be shared across all objects of the class. Imagine you wanted to establish a unique ID number to each object. Keeping a static field for the next free ID would be handy.
  5. But there's one little problem, what is the value of num initially? Shouldn't it be 0? But we can't initialize it because we don't have an object yet in order to name it. The answer is to use the name of the class not the name of a variable instance of the class. We could make num 0 by saying Point.num=0;
  6. Stylistically, since we can always access num via the class name instead of a variable name, it has become preferred that we always do. This way it signals to the reader of our code that this is not a regular member field.
  7. Another use for the static modifier on fields is in conjunction with final. Final means that the value of this thing cannot be changed, which makes it good for a constant:
    
          class Tools {
            final double SQRT2 = 1.41421356;
          ...}
        
    but the problem with this is we couldn't access this thing without creating an object of type Tools:
          Tools t = new Tools();
          double d = t.SQRT2;
        
    That seems wasteful, but if static fields exist even when no objects of that type exist, thaen we can declaer it as:
          class Tools {
            final static double SQRT2 = 1.41421356;
          ...}
        
    and access it directly using the class name:
    
          double d = Tools.SQRT2;
        
  8. We've seen the keyword static also applied to methods, and we said this means we're "not doing OOP, but rather structured/procedural programming." This is sort of right, but it's more complicated than that.
  9. A static method still is a member method of that class, but like static fields, it is not associated with any particular object. What this means is that inside this method, you cannot access any member fields that are not static. If we added the following to Point:
          static int foo() {
            return x;
          }
        
    we would get a compile time error: "non-static variable xcannot be referenced from a static context."
    but we could access static fields:
          static int foo() {
            return num;
          }
        
  10. Static methods are used in 2 cases:
    1. When we only want to access static fields in the class, like the example above.
    2. When we don't need to access any of the state of an object because all the information we need is in the arguments. This is usually for utility functions that are best called in a structured/procedural way. The built in math functions are all examples of that: Math.pow(3,2);
  11. Wait, what about main()? Why is that static? well, main isn't really special at all, it's just another method in another class. Look at how we run our program form the command line: java Main.
  12. What happens is not that your program starts running at main() the way it does in C++, but we start running in the virtual machine, and the vm is instructed to call the static method in the class you passed as an argument on the command line: Main.main(s);
  13. Does that mean we could have instructed it to start differently? absolutely! We can put a main() method in every class we write. Try adding main to our point class and running that: java Point
  14. So where should we put main? When java first came out, it was common to create all your classes that you might need, and select one and put main in that. That went well with the OOP philosophy that data is the most important (see how we're adding methods to data? the data comes first) but over time I see more and more that you create a special class that holds nothing but main(). This organizes the program better and makes more sense to beginning students. Since netbeans endorses it, I now consider it canon.
  15. Do we ever put main in other classes? Yes, all the time, we put testing code in the main of each class! We can spend a lot of time working on a class, but how do you know it works? Sometimes you have to wait for the rest of the program to be written to test it. But you could put testing code for that class in the main() in that class, so you can try it out before plugging into the rest of the program.

Moving on to the other modifiers

  1. The other modifiers we have seen are public and private, and we'll talk about one more, protected.
  2. public on a class means that anyone can create on onbject of that class. Most of the time we will want our classes public.
  3. In fact, why aren't all classes public? We've seen an example already, inner classes. If a class is defined inside another class, then we don't want outside access. We can make the inner class private and no one outside can get to it. What might happen if we make out inner class public?
          Class.Inner v = new Class.Inner()
        
    yuck, that breaks all our encapsulation.
  4. what about no keyword? This is called making the class package-private. What this means is that the class is visible to other classes if and only if the other class is in the same package.
  5. So what's a package? It's a grouping of related files explicitly bundled together. As a programmer you might create a collection of classes for a single purpose in a larger project, such as all the math related classes in a physics game. So you can put them together as a package. Netbeans does that by default.
  6. One main reason for packages is uniqueness of names, you can have the same name of a class as someone else on the project if they both are in different packages. One style that has developed is to name all your packages after your domain name in reverse: package edu.usna.cs.thispackagename. This helps manage unique names.
  7. if you want to use something in another package, you have to reference it by name: java.util.Scanner s = new java.util.Scanner(in); or you can import it: import java.util.Scanner; Importing everything in a packages, makes name conflicts more likely.
  8. New thing in the lates java: you can import static methods too! import static java.lang.System.*;
  9. To put something in a package, you put that package line as the first real line in your file. With no package line the file is still in a package, called the default package, along with everything else without a package name.
  10. here's the annoying bit, you need to then place te file in a directory structure that matches the package name: ./edu/usna/cs/thispackagename, so the compiler know where to look. Note that this is exactly what netbeans does for us. In this case, everything needs to be compiled and run from the base directory.
  11. What about the keywords for things inside classes? For both fields and methods, they work the same way.
  12. This handy table from Sun explains it:
    Access Levels
    Modifier Class Package Subclass World
    public Y Y Y Y
    protected Y Y Y N
    no modifier Y Y N N
    private Y N N N
    ignoring that subclass column (we'll get back to that next week) this shows us all we can do, and introduces a new word, protected.
  13. Note that no keyword is package access, combined with everything being in the default package, would make it the same as public! That breaks our encapsulation. Be careful with that. If you explicitly want package access, you might want the protected keyword.