Except where otherwise noted, the contents of this document are Copyright 2013 Stuart Reges and Marty Stepp.
lab document created by Marty Stepp, Stuart Reges and Whitaker Brand
Goals for today:
Object code?Objects are another type of class, one which has both data and behavior.
So far, we've just written client code. Now we're learning how to write Object code. With client code, the main method is run. With Object code, we're writing a blueprint so that client code can create as many of our Object as it wants!
Up until now, we've only used Objects implemented by others (what does the code for Scanner or Random look like? We've never seen it!) 
Now, we're going to explore how to write a complete Object.
  With client code, the main method is executed. With Objects, when the client constructs a new Object, that Object's constructor is called. A constructor is a special type of method where the Object's default features should be set (more on this later).
public class Point {
   // constructors have no explicit return type
   // constructors should not be static
   public Point() {
      ...
   }
}
Point Object?
	
  Constructors can also take parameters. As long as they don't have the same method signature, an Object can have any number of constructors.
public class Point {
 
  // these 4 constructors have a unique #, type, or ordering of parameters
   public Point(int x, int y) { ... }
   public Point(int x) { ... }
   
   public Point(String s, int x) { ... }
   
   public Point(int x, String s) { ... }
   // this constructor isn't okay, because we already have a constructor that takes 2 ints
   public Point(int y, int x) { ... }
}
| 
public class Point {
   public Point() { ... }
   public Point(int x, int y) { ... }
   public Point(int y, int x) { ... }
} | illegal | |
| 
public class Point {
   public Point() { ... }
   public Point(int x, String s) { ... }
   public Point(String s, int x) { ... }
} | legal | 
    Remember that our definition of an Object is that it has both data and behavior. Fields are what allow us to have data! They should reflect the state of the Object!
  
Fields are variables that are declared outside of any method/constructor, which makes them accessible in any method/constructor. This means that fields are great for remembering information across method calls.
public class Point {
   
   // the (x, y) values represent the state of a Point
   int x;
   int y;
   
   public Point() {
     ...
   }
}
| type | default value | 
|---|---|
| int | 0 | 
| double | 0.0 | 
| char | '\0'(null character) | 
| String(or any otherObject) | null | 
| boolean | false | 
In the constructor, we can change the initial values of our fields to a literal value, or even to a parameter passed in to the constructor! Either way, for the purposes of this class, it is better style to initialize the values of the fields in the constructor. Field values should not be set where they're declared.
If we give a parameter the same name as a field, we need to use the keywordthis to refer to the field.
public class Point {
   int x;
   int y;
   // fields should be initialized in the constructor
   int z = 5;
   int z;
   public Point(int x, int y) {
      // "this" keyword lets us set fields x/y to parameters x/y
      this.x = x;
      this.y = y;
      // could also write this.z, but unnecessary, since there is no local variable z
      z = 5;
   }
}
  Suppose you have the following Point class (on the left) and client code (on the right):
  
| 
public class Point {
   public Point(int x, int y) {
      ...
   }
} | 
public class PointClient {
   public static void main(String[] args) {
      // make a new point here
   }
} | 
Point?
	
int x = 5;
int y = x;
x = 10;
// here, x = 10, y = 5
Setting y = x meant y =  the value that x had at that point in time. y does not change values when x changes values.
int[] a = new int[5]; // a ==> [0, 0, 0, 0, 0] int[] b = a; // a ==> [0, 0, 0, 0, 0] <== b a[0] = 10; // a ==> [10, 0, 0, 0, 0] <== b b[1] = 8; // a ==> [10, 8, 0, 0, 0] <== bSetting
b = a means b and a now reference the same array. Changes to either a or b change both a and b. 
    What we did on the last slide wasn't actually great style--generally, we don't want clients to be able to directly modify the state of Objects. 
  
    To prevent clients from directly changing our Object's fields, we need to make our fields private--this is called encapsulation!
public class Point {
   private int x;
   private int y;
   public Point() {
      ...
   }
}
  
Object code
    With client code, we implement static methods that the main method (or other methods!) call. With Object code, we want to implement instance methods. Instance methods are non-static, and are called on an instance of an Object.
  
We've actually used instance methods before!
// console is an instance of a Scanner! Scanner console = new Scanner(System.in); // .next() is an instance method, as it's called on an instance of a Scanner! String input = console.next();
| 
public class Point {
   
   // class constants are fine!
   // fields
   private int x;
   private int y;
   
   // constructor!
   public Point(int x, int y) {
      this.x = x;
      this.y = y;
   }
   // instance method! Returns the value of x
   public int getX() {
      return x;
   }
}
 | 
public class PointClient {
  
   // class constants are fine!
   // no variables besides class constants should
   // be outside of methods
   // main method
   public static void main(String[] args) {
      Point p = new Point(5, 10);
      // calls an instance method on a Point instance
      int xCoord = p.getX();
      printX(xCoord);
   }
   
   // static method, even if a bit trivial
   public static void printX(int xCoordinate) {
      System.out.println(xCoordinate);
   }
}
 | 
Special methods: toString
    There is a contract in Java that when an instance of an Object needs to be put into String form (ex. printing, String concatenation), the Object's .toString() method will be called. If you write an Object class without writing a .toString() method, a default one will be used and gibberish will be printed.
  
    When you write a .toString() method, you are overriding the default .toString() method. What this means isn't important, except for the fact that it is critical to spell/capitalize correctly.
// good! Correct spelling/capitlization, will override the default .toString()
public String toString() {
   ...
}
// will not override the default .toString()!
public String tostring() {
  ...
}
Nice job making it this far--labs are tough! Feel free to work with the person next to you for the remaining slides. Labs are a unique opportunity (unlike homework) to collaborate directly on ideas, and practice peer programming.
These next problems get a little more challenging as we explore earlier concepts further.
We put a lot of problems in here so that you have plenty to refer back to later when working on homework. Don't feel bad if you don't finish all of them--Brett can't finish them all in a 50 minute lab, either! :)
 
Forest the cat says good job!
If you finish all the exercises, try out our Practice-It web tool. It lets you solve Java problems from our Building Java Programs textbook.
You can view an exercise, type a solution, and submit it to see if you have solved it correctly.
Choose some problems from the book and try to solve them!