Unit 5: More on Classes/Objects Notes AP CS A The Difference between Primitive and Object/Reference Data Types First, remember the definition of a variable. A variable is a. So, an obvious question is: what is stored in a particular variable? For primitive data types (e.g. ) the answer is easy. The variable stores the data. int x = 78; int y = x; For object variables, the answer is more complicated. An object variable contains a to an object - not the object itself. Point p1 = new Point( 3, 4 ); Point p2; p2 = p1; 1. How many Point objects does this code create? 2. How many Point objects does this code create? Point x1; Point x2; Point x3 = new Point( 17, -22 ); Point x4 = x3; is a special value that can assigned to any object variable. This indicates that the variable does not contains a reference to an object. Reference variables can be initialized with a value of null. For example: Point p1 = null; To check if a variable has a value of null, use ==. For example: public void dosomething( String x ){ if ( x == null ) x does not contain a reference to a String object Page 1
If you attempt to call a method but the object variable does not contain a reference to an object, then you will get this runtime error:. For example: Point pt = null; double d = pt.distance( 0, 5.5 ); // If an object is instantiated but at some later time no variable contains a reference to that object, the JVM will delete that object in a process called. For example: Point man = new Point( -1, 0 ); man = null; // Why public and private? When someone uses an object, they don t usually need to know how an object does something; they only need to know what an object does. For example, we ve been using Scanner objects without ever seeing the actual code inside that class. This is similar to how we use everyday objects. In the process of writing a class, we have (so far) always made the instance variables private and everything else public. Let s consider why making instance variables private is useful. Look over the code below. public class Person1{ private int age = 8; public int get(){ return age; public void set(int n){ age = n; public class Person2{ public int age = 9; // another class Person1 p1 = new Person1(); Person2 p2 = new Person2(); System.out.println( p1.get() ); System.out.println( p2.age ); p1.set( 24 ); p2.age = 25; System.out.println( p1.get() ); System.out.println( p2.age ); The above code compiles and runs. What is displayed? The Person1 and Person2 classes do the same thing. Unfortunately, both have a design flaw How can the flaw be fixed in the Person1 class? How can the flaw be fixed in the Person2 class? This is one reason to make the instance variable private and then write getter and setter methods. Also, if an instance variable is public then you cannot change its name, or data type, without breaking any code that uses this class. Conclusion: Page 2
The of an object refers to the current values of all its instance variables. If the value of even one instance variable changes, then the state of the object has changed. Two methods in the same class are if they have the same name but different parameters. Two methods in the same class cannot differ by just their. Default Constructors. If a class does not define a constructor, it automatically has one. All instance variables are given default values. ints and doubles have default values of booleans have a default value of reference (aka object) variables have a default value of public static void ( String [] args ){ public class Panda { private int x; public int get(){ return x; IMPORTANT. If you write even one constructor, then you lose the default constructor. The Scope of a variable refers both to its lifetime and its accessibility. Lifetime means how long does the variable exist and accessibility means who can see/use the variable. Variable Lifetime Accessibility public instance variable Any class that can access the object. private instance variable parameters in a constructor or method local variables in a constructor or method Only the constructors and methods within its class. Only the constructor or method that it is declared in. Only within the block that it is declared in. A block of code is a section of code that is explicitly or implicitly contained with a pair of curly braces. Page 3
Heap vs. Stack. Memory to run a program can be divided into the heap and the stack. The heap is for objects (and other things) and the stack is for local variables and parameters. Each call to a method generates a new stack frame for that method. 1 2 3 4 public class Practice { public static void ( String [] args ) { Dog a = new Dog( 2 ); int z = 5; z = a.bark( 3 ); System.out.print( z ); 5 6 7 public class Dog{ private int w; public Dog(int x){ w = x; public int bark(int y) { int n = y + w; return n; Line currently being executed Stack Heap 1. The method is called. 2. The Dog constructor is called and a new stack frame is generated constructor Completion of line 2. The stack frame for the constructor is removed. 3. Another local variable is declared. 4/5. The bark method is called and a new stack frame is generated. bark 6. A local variable in the bark method is declared. bark 7. The value of n is returned and assigned to z. The stack frame for the bark method is deleted. Page 4
this. Within an instance method or a constructor, this is a reference to the current object the object whose method or constructor is being called. You can refer to any member of the current object from within an instance method or a constructor by using this. - http://docs.oracle.com/javase/tutorial/java/javaoo/thiskey.html In many circumstances, the use of this is optional. Compare these two versions of the same class. The Way We Write a Class The Way Some People Like to Write a Class public class Square{ public class Square{ private int side; private int side; public Square( int s ){ side = s; public Square( int s ){ this.side = s; public int area(){ return side * side; public int area(){ return this.side * this.side; Some people think that the version on the right makes it clearer that we are changing the value of the instance variable of the current object. Here s some sad code where the use of this is required. In this example, every Ape that is created must immediately be added to a Zoo. public class Zoo{ public class Ape { private String names = ""; private String name; public void add( Ape a ){ names += a.get() + " "; public String getnames(){ return names; All of this code compiles and runs. What is displayed when the Runner class is executed? public Ape( String s, Zoo z ){ this.name = s; z.add( ); public String get(){ return name; public static void (String [] args){ Zoo z = new Zoo(); Ape a1 = new Ape( "Bob", z ); Ape a2 = new Ape( "Ann", z ); String s = z.getnames(); System.out.println( s ); Page 5
You can access the private instance variables of a parameter IF the parameter is an object of that class. For example: public class Box{ private int width; public static void ( String [] args ){ private int length; Box b1 = new Box( 3, 6 ); Box b2 = new Box( 5, 4 ); System.out.println(b1.biggerThan( b2 )); System.out.println(b2.biggerThan( b1 )); public Box( int wid, int len ){ width = wid; length = len; public boolean biggerthan( Box b ){ int my_area = this.width*this.length; int other_area = b.width * b.length; return my_area > other_area; Constants. Sometimes you want to create a variable that never changes. For example: public class Bill{ private final double TAX_RATE = 0.1; public static void ( String [] args ){ private double total = 0; Bill b = new Bill(); public double add( double item ){ total += item + item*tax_rate; return total; Use the keyword final to make a variable a constant. double x = b.add( 10 ); System.out.println( x ); x = b.add( 20 ); System.out.println( x ); It is customary to use all upper-case characters for a constant s name. Constants improve your code s readability and tainability. Trying to change the value of a constant generates a compiler error. Functional Decomposition is the process of breaking a method into Smaller, more focused methods are The helper methods will almost always be. After function decomposition, a method should be easier to understand and may be shorter than the original code. You should think of using Page 6
It can look something like this: First Version public return_type method( parameters ){ section A (some lines of code) section B (some lines of code) section C (some lines of code) After Functional Decomposition public return_type method( parameters ){ methoda( parameters ); methodb( parameters ); methodc( parameters ); private return_type methoda( parameters ){ code private return_type methodb( parameters ){ code private return_type methodc( parameters ){ code Here s a more concrete example. The purpose of the method is to print out a grid similar to the one shown. The size of the grid depends on the parameter. In the figure to the right, size is 5. +++++++++++++++ 0 1 2 3 0 1 2 3 0 1 2 3 0 1 2 3 0 1 2 3 0 1 2 3 0 +++++++++++++++ First Version public void method( int size ){ for ( int k = 0; k < size; k++ ) System.out.print( "+++" ); System.out.println(); int x = 0; for ( int row = 0; row < size; row++ ){ for ( int col = 0; col < size; col++ ){ if ( x == size-1 ) x = 0; System.out.print( " " + x + " " ); x++; System.out.println(); After Functional Decomposition public void method( int size ){ printplus( size ); Notice how printnumbers( size ); we call these printplus( size ); methods. private void printplus( int size ){ private void printnumbers ( int size ){ for ( int k = 0; k < size; k++ ) System.out.print( "+++" ); System.out.println(); Page 7