360 likes | 531 Views
Classes and Objects. Key Idea. Classes and Objects. Class: describes the form of an object, a template or blueprint or mold specifies data representation, behavior, and inheritance (via variables, methods and parents). Object:
E N D
Key Idea Classes and Objects Class: describes the form of an object, a template or blueprint or mold specifies data representation, behavior, and inheritance (via variables, methods and parents) Object: an instance of a class — has unique copy of every non-static variable (i.e., the “instance variables” but not the class variables). Difference between “a class and an object of that class” is analogous to the difference between “a type and a variable of that type”. Naming Conventions: Classes: Identifiers begin with cap letters for each word in the Identifier, e.g., class NeuralNetwork Objects: Identifiers begins with lower case letter, then caps for other words in identifier, e.g., thisObjectIdentifier
Specification of a Class class Box { int iLength; int iWidth; int iHeight; public void setLength (int iNewLength) { iLength = iNewLength; } // of setLength public int getLength ( ) { return (iLength); } // of getLength public void setWidth (int iNewWidth) { iWidth = iNewWidth; } // of setWidth public int getWidth ( ) { return (iWidth); } // of getWidth public void setHeight (int iNewHeight) { iHeight = iNewHeight; } // of setHeight public int getHeight ( ) { return (iHeight); } // of getHeight public int getVolume ( ) { return ( getLength( ) * getWidth( ) * getHeight( ) ); } // of getVolume } // of class Box Use accessors and modifiers!
Usage tip Box sampleBox = new Box(); sampleBox.iLength = 10; Legal? Preferred: sampleBox.setLength(10); Why?
Constructors • Default provided unless... • Must have same name as class • Must not have return type (if you want a constructor) • Multiple constructors typical • Each must have unique signature • number, type, order of parameters
Example class Box { int iLength; int iWidth; int iHeight; public Box() { } // Default constructor public Box(int iL, int iW, int iH) { iLength = iL; iWidth = iW; iHeight = iH; } // Box Constructor // class definition continues... Comments omitted for clarity?
Example class Box { int iLength; int iWidth; int iHeight; public Box() { this(0, 0, 0); } // I can even do this... public Box(int iL, int iW, int iH) { iLength = iL; iWidth = iW; iHeight = iH; } // Box Constructor // class definition continues...
Creating Instances of Classes • Involves three things: • 1. Creating the reference: Box thisBox ; • 2. Instantiating the object:thisBox = new Box( ); • OR do first two steps at once, e.g., • Box thisBox = new Box( ); • 3. Having constructor(s) set initial values: • public Box • (int iNewLength, int iNewWidth, int iNewHeight) { • setLength (iNewLength); • setWidth (iNewWidth); • setHeight (iNewHeight); • } // of constructor • With an appropriate constructor, we can do all three at once: • Box thisBox = new Box (10, 5, 25);
If you just understand one thing... • ...it should be what we mean by a reference. • Every object created in Java is created in the dynamic area of memory (heap). • The creation operation involves the return (to you) of the location of the object. This is known as a reference. It is the same idea as a pointer. Box someBox; // This creates a reference someBox = new Box(10, 20, 30); // We create the new box and stick its // reference in someBox
Objects and References Distinguish between primitives and objects. Assignment with Primitives: Code: Memory: int x; x x y int y; 5 x y x = 5; y = x; 5 5 x y
Box box1; Box box2; box1 box2 box1 box2 box1 = new Box(8, 5, 7); L=8, W=5, H=7 box2 = box1;// note: two references// but only one object L=8, W=5, H=7 box1box2 L=3, W=9, H=2 box1box2 box1 = new Box(3, 9, 2); L=8, W=5, H=7 box1 = box2; // Old reference lost! L=3, W=9, H=2 box1box2 L=8, W=5, H=7 Objects and References Assignment with References to Objects: Code: Memory:
Our Next Real Challenge • Java only has “in” parameters public void swap(int a, int b) { int temp; temp = a; a = b; b = temp; } • We can return values from functions but this won’t be enough. • When a parameter is a reference to an object • We can access the object’s methods • We can make persistent changes
Pop Quiz! class Pop { public static void swap(int x, int y) { int t; t = x; x = y; y = t; } // swap public static void main(String args[]) { int a = 7; int b = 99; swap(a, b); System.out.println("a = " + a + " b = " + b); } // main } // Pop What prints?
The pseudocode for our Example algorithm Compute_Grade // Calculates the course grade based // on the student’s assignments prog_avg, quiz_avg, lab_avg, exam_score, grade_avg isoftype Num Get_Data(prog_avg, quiz_avg, lab_avg, exam_score) grade_avg <- Average(prog_avg, quiz_avg, lab_avg, exam_score) Output_Grade(grade_avg) // Outputs letter grade endalgorithm
The pseudocode for Get_Data procedure Get_Data (prog, quiz, lab, exam isoftype out Num) // Purpose: Prompts user for data & returns them // Pre-condition: none // Post-condition: passes values back to point of call print(“Enter your program average:”) read (prog) print (“Enter your quiz average:”) read (quiz) print (“Enter your lab average:”) read (lab) print (“Enter your exam score:”) read (exam) endprocedure //Get_Data
How do we do this in Java? Make a Grade class which contains a single grade value and some accessor/modifier methods. Figure out how to do Get_Data: Pass in references to grade objects. Get necessary values from user Use grade objects methods to set values
Java code for Grades Class public class Grade { String name; double value; public Grade(String newName) { name = newName; } // Constructor public void setValue(double v) { value = v; } public double getValue() { return value; } public void setName(String n) { name = n; } public String getName() { return name; } } // Grade
Java code for Main Algorithm class Compute_Grade { <other stuff> /** * Calc course grade based on the assignments */ public static void main(String[] args) { double grade_avg; Grade prog = new Grade(“Program”); Grade quiz = new Grade(“Quiz”); Grade lab = new Grade(“Lab”); Grade exam = new Grade(“Exam”); get_Data(prog, quiz, lab, exam); grade_avg = average( prog, quiz, lab, exam ); output_Grade( grade_avg ); } } // end of class Compute_Grade
Java code for Get_Data // Still inside the class Compute_Grade /** * Purpose: Prompts user for data & returns them * Pre-condition: none * Post-condition: passes values back to point of call */ public static void get_Data(Grade g1, Grade g2, Grade g3, Grade g4) { g1.setValue( IOGadget.readDouble("Enter “ + g1.getName() ); g2.setValue( IOGadget.readDouble("Enter “ + g2.getName() ); g3.setValue( IOGadget.readDouble("Enter “ + g3.getName() ); g4.setValue( IOGadget.readDouble("Enter “ + g4.getName() ); } //Get_Data
All Container Classes you build should be Generic • Generic classes are [almost] trivial to build • Every class is derived from the class Object • Make this the type of the contained data • An object of any type can then be put into the container • You have to cast the object on output to its specific class The “almost”: • Primitive data types [int, char, double] don’t work like this • your first, trivial example programs need a little TLC • each atomic data element has a corresponding wrapper class for this purpose • e.g. the Integer class is an Object-type container for an int.
The Object Class provides Basic Methods • clone() • Creates a clone of the object. • Used to make a deep copy • equals(Object) • Compares two Objects for equality. • getClass() • Returns the Class of this Object. • hashCode() • Returns a hashcode for this Object. • Used for indexing this object with others • toString() • Returns a String that represents the value of this Object. • Used implicitly by print() to “stringify” the object • And some others we’ll deal with later, perhaps. Why?
Overloading Object’s Methods • Each of these methods does something generic. • However, with the exception of getClass(), they should all be overloaded when you write a specific class • consider them as virtual methods • should be implemented specifically in derived classes • generic behavior is not usually what you want • e.g. hashCode() will be unique to every instance of class Object [some representation of its memory address]. • However, you probably want objects with identical content to return the same hashCode.
Example of a Linked-List Node Pseudocode: LL_Node isoftype record data isoftype <generic type> next isoftype Ptr toa LL_Node endrecord // LL_Node data next
First a Node public class Node { private Object data; public Node( Object d ) { setData( d ); } // Constructor public void setData( Object d ) { data = d; } public Object getData() { return data; } public String toString() { return ( data.toString() ); } public Object clone() { return new Node( data ); } public int hashCode() { return data.hashCode(); } Ok?
Subtle Bug // public class Node (continued) public static void main(String args[]) { Node n = new Node("Hello!"); System.out.println("Should be Hello: " + n); n = new Node(null); System.out.println("Should be null: " + n); } // main }// Node Should be Hello: Hello! Exception in thread "main" java.lang.NullPointerException: at Node.toString(Node.java:10) at java.lang.String.valueOf(String.java:1911) at java.lang.StringBuffer.append(StringBuffer.java:365) at Node.main(Node.java:25)
First a Node public class Node { private Object data; public Node( Object d ) { setData( d ); } // Constructor public void setData( Object d ) { data = d; } public Object getData() { return data; } public String toString() { if(data == null) return "null"; else return data.toString(); } public Object clone() { return new Node( data ); } public int hashCode() { // need to deal with potential null here too return data.hashCode(); }
Now the Linked-List Node class LLNode extends Node { private LLNode next; public LLNode( Object d, LLNode n ) { super( d ); set_next( n ); } public void setNext( LLNode n ) { next = n; }; public LLNode getNext() { return next; }; public String toString() { return ("{ data = " + super.toString() + "; next = " + next + " } " ); } } // LLNode