Objects in Java: Grouping Data

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
  1. As we've seen classes/objects can be used like structs to group together hunks of data as a new type, but there actually many other important properties.
  2. As you may have noticed, programs can sometimes get complicated. Object Oriented programming is a way of organizing programs to try to manage this complexity. It does this com allowing classes to hold not just data, but also the methods that operate on the data.
  3. In structured/procedural programming, you have functions as the basic units of the program, and they operate on the data. In OOP, the basic units are the objects, and they contain the code that tells those objects how to behave.
  4. Let's look at an example
      class Player {
        int row,col;
        int facing;
    
        public void turnLeft() {
          facing = (facing+1)%4;
      }
    
  5. This code looks just like the player class you already wrote for the lab, but notice how there is a method that is included inside the definition of the class. Also note how the word static disappeared.
  6. We could have done this the old way of course. Take a look at this for comparison:
      class Player {
        int row, col;
        int facing;
      }
      public static void turnLeft(Player p) {
        p.facing = (p.facing+1)%4;
      }
    
  7. The Object Oriented version does not have any different functionality. It is simply a way of organizing things. The next few weeks will be about the advantages of this system.
  8. The method above is called a member-method, because it is a part of the class itself.
  9. See how the member method modifies the facing variable. It just does it with out mentioning a variable of type Player. So how does it know which player it is that is turning left? That is made clear in the call:
      Player one = new Player();
      Player two = new Player();
      one.turnLeft();
      two.turnLeft();
    
    Compare that to:
      Player one = new Player();
      Player two = new Player();
      turnLeft(one);
      turnLeft(two);
    
    So we see that when we call the member method, the way we call it determines which player it is being called on.
  10. I like to think of it as, when calling a member method (sometimes called invoking the member method), there is an automatic first argument that doesn't go inside the parentheses.
  11. When we mention a variable in the class (called a member field in Java), the method knows that it is the one that is inside the object that called the method.
  12. Another way to think of it is that every object has its own copy of the method inside it, and you call it by first mentioning the object, then using the dot to get inside the object, and then mentioning the method name. Thus when the method is running, when a variable is mention, it first looks locally inside the method. If it doesn't find it, it then looks in the wider scope of the object to find it there.
    Diagram belongs here
    
  13. Assuming a turnRight() method similar to turnLeft(), What is the output of the following:
      Player one = new Player();
      Player two = new Player();
      one.facing = 0;
      two.facing = 0;
      turnLeft(one);
      turnRight(two);
      System.out.println("one: " + one.facing + " two: " + two.facing);
    
  14. Each method call modifies just the object that invoked it.
  15. Now, notice how I initialized the objects in the code above? Of course, that only did 1/3 of the job. The whole thing is kind of messy and ugly. Too many lines of code. We could make a special function, that's what I did:
      Player one = new Player();
      Player two = new Player();
      initPlayer(one,20,0,0);
      initPlayer(two,20,39,2);
    ...
    
  16. But now we know we could add that method to the class to better organize it:
      class Player {
        class Player {
        int row,col;
        int facing;
    
        public void initPlayer(int r, int c, int f){
          row = r;
          col = c;
          facing = f;
        }
    
        public void turnLeft() {
          facing = (facing+1)%4;
      }
    ...
      Player one = new Player();
      Player two = new Player();
      one.initPlayer(20,0,0);
      two.initPlayer(20,39,2);
    
  17. This is common enough that we have a special way of initializing objects using a method called a constructor.
  18. The constructor is a member method that has the SAME NAME AS THE CLASS. It has no return type.
  19. Arguments to the constructor are passed when the object is made:
      class Player {
        class Player {
        int row,col;
        int facing;
    
        public Player(int r, int c, int f){
          row = r;
          col = c;
          facing = f;
        }
    
        public void turnLeft() {
          facing = (facing+1)%4;
      }
    ...
      Player one = new Player(20,0,0);
      Player two = new Player(20,39,2);
    
  20. Nice how it cleans up the code we see in main, isn't it?
  21. In Java we can overload methods the same way we can overload functions in C++. This is common when it comes to constructors because we might not have all the information we need to initialize an object:
      class Player {
        class Player {
        int row,col;
        int facing;
    
        public Player(int r, int c, int f){
          row = r;
          col = c;
          facing = f;
        }
        public Player() {
        //defaults
          row = 0;
          col = 0;
          facing = 0;
        }
      }
    
  22. Just like C++, Java selects the version of the method to call based on the number and type of the arguments.