Upload
william-willis-owen
View
213
Download
0
Embed Size (px)
Citation preview
Instance vs. ClassInstance vs. ClassDeclarationsDeclarations
Don’t be fooled. Just because a variable might be declared as a field within a class – that does *not* imply that it is a “class variable.”
It could be:1. a class variable, or2. an instance variable!
Likewise, each method is indeed declared within a class, but that does *not* imply that it is a “class method.”
It could be:1. a class method, or2. an instance method.
“Class variable” and “class method” both mean something very specific.
InstanceInstance vs. vs. ClassClass Declarations Declarations
A distinction that applies to both variables and methods
An instance <variable or method> is one that belongs to each object of a class.
A class <variable or method> is one that belongs only to the class itself. (N.B. It will be accessible to the objects)
The keyword static:
• indicates a class variable or class method.
• absence of the keyword static indicates an instance variable or instance method.
InstanceInstance vs. vs. ClassClass Declarations Declarations
Declares a name String for each instance. Thus, each Human will have its
own name. But . . . Also declares a population counter for each instance of Human.
Instance vs. Class Variables
Suppose we wanted to track the total number of objects created.
Consider:
class Human {String name;int population = 0;
public Human(String name) {this.name = name;population++; //WRONG!
} // of constructor
} // of HumanThus, each Human will have its own
population variable, each having a value of 1. This makes no sense!
class Human {String name;static int population = 0;
public Human(String name) {this.name = name;
population++; } // of constructor
} // of Human
Instance vs. Class Variables
Each instance will still have a String name
Thus, each Human will have its own name.
NOTE: Each Human does not get a population counter.
This declares a single population counter for the class Human itself. It is a class variable.
Thus, each Human will increment this single shared counter by 1.
One change!
Instance vs. Class Variables:When to Use
Use instance variables whenever each object should have its own variable.
E.g., attributes of the particular object. name, ssn, age, weight
Use a class variable whenever the class itself should maintain a single copy of datum pertaining to all instances of the class.
E.g.,
population counts summary dataassigning lot numbers shared resources.
Quiz Alert!
Quiz Alert!
Instance vs. Class Variables
Constants Revisited:
class ConstantExample { final int iMAXSIZE = 10;} // of ConstantExample
class ConstantExample { static final int iMAXSIZE = 10;} // of ConstantExample
Declares a different-but-identical constantfor each instance of the class.
Wasteful with zero benefit.
Declares a single constant for use by all instances of the class.
We now see the reason behind declaring most constants as ‘static’ as well as ‘final’.
Quiz YourselfQuiz Yourself
public class Test {
public void sayHello() {
System.out.println (“Hello”);
}
public static void main (String arg[]){
sayHello();
}
}
Consider why the following code will notnot compile:
Classes and ObjectsClasses and Objects• The error produced is:
“Can't make static reference to method void sayHello() in class test.”
• Why? The answer lies in the difference between objects and classes. As noted in previous slides, classes are composed of member objects, primitives and methods. When properly designed, classes provide state and behavior for objects.
• As an OO language, Java emphasizes the use of objects to manipulate data. Thus, we must make instances of a class in order to drive a program.
public class Test {
public void sayHello() {
System.out.println (“Hello”);
}
public static void main (String arg[]) {
sayHello(); // WRONG!
}
} }//class Test
public class Test {
public void sayHello() {
System.out.println (“Hello”);
}
public static void main (String arg[]) {
sayHello(); // WRONG!
}
} }//class Test
public class Test {
public void sayHello() {
System.out.println (“Hello”);
}
public static void main (String arg[]) {
sayHello(); // WRONG!
}
}//class Test
Another PerspectiveAnother Perspective
public class Test {
public void sayHello() {
System.out.println (“Hello”);
}
public static void main (String arg[]) {
sayHello(); // WRONG!
}
}//class Test
When we create the class Test, there are potentiallyan infinite number of instances available.
Test t1 = new Test(); Test t2 = new Test(); // etc.
t1
t2
t3
public class Test {
int x;
static int y = 2;
}//class Test
CLASS INSTANCES
Test t1 = new Test();t1.x = 5; // should use accessor
Test t2 = new Test();t2.x = 3; // should use accessor
public class Test {
int x; // now 5
static int y; // 2
}//class Test
public class Test {
int x; // now 3
static int y; // 2
}//class Test
New class instances (objects) get unique copies of every member--except for static or “class” members. We can think of static as meaning “only one copy”
static int y;
static int y;
t1
t2
So, when Java encounters our class, it sees:
* a potentially infinite number of Test instances, each with their own behavior (sayHello() ), and
* only one (static) main shared between all the classes
public class Test {
public void sayHello() {
System.out.println (“Hello”);
}
public static void main (String arg[]) {
sayHello(); // WRONG!
}
}//class Test
public class Test {
public void sayHello() {
System.out.println (“Hello”);
}
public static void main (String arg[]) {
sayHello(); // WRONG!
}
}//class Test
t2
t1
public class Test {
public void sayHello() {
System.out.println (“Hello”);
}
public static void main (String arg[]) {
sayHello(); // WRONG!
}
}//class Test
Thus, the error of making a “static reference to a method” might be understood as a problem of ambiguity.
We have not told Java which of the many possible instances of class Test we intend to call “sayHello()” on.
Only one
Potentiallymany
Class vs. Instance MembersClass vs. Instance Members
class test {public void sayHello(){ // etc. etc.}
}//class test
class test {public void sayHello(){ // etc. etc.}
}//class test
class test {public void sayHello(){ // etc. etc.}
}//class test
The “class” or static members are defined for all instances. Every instance has access to static members, and can change them for all other members.
CLASS INSTANCES
SHARED BY ALL
class test { public void sayHello(){ // etc. etc }
public static void main (String[] argv) {
}
}
Solution ISolution I
public class Test {
public void sayHello() {
System.out.println (“Hello”);
}
public static void main (String arg[]) {
Test t = new Test();
t.sayHello(); // Corrected
}
}//class Test
One merely needs to resolve this ambiguity to correct the program. Thus, just make an instance of the class, and reference/invoke the object’s members.
OROROROR
Solution 2Solution 2
public class Test {
public static void sayHello() {
System.out.println (“Hello”);
}
public static void main (String arg[]) {
sayHello(); // Corrected
}
}//class Test
One merely needs to eliminate this ambiguity to correct the program. Thus, just make the method static.
WarningWarning
You will find this course very difficult, if not impossible, if you did not grasp the previous slides.
Misuse of static is the second most pernicious bug found in previous courses.
Do you follow this?Do you follow this?public class Ouch { int w = 0; static int x = 0; final int y = 0; final static int z = 0;
public static void main(String [] args) { Ouch one = new Ouch(); Ouch two = new Ouch(); Ouch three = new Ouch(); // see questions } // main} // Ouch
How many w’s are in memory?How many x’s? How many y’s? How many z’s? Are any constant?
Little secretsLittle secretsClass methods and class variables exist and
can be used even when *no* objects have been instantiated!
Instance methods and instance variables do not exist on their own, but only as part of an instance.
Objects can be used to access both class and instance members.
Classes can be used to access only class members!
Questions?Questions?
AnnouncementsAnnouncements
• Read webpage continuously!
You are playing a risky game without it!
String-FuString-Fu
Strings vis-a-vis ObjectsStrings vis-a-vis ObjectsEvery String is an instance of Java’s built-in class String.
Thus, Strings are objects.
Java provides extra support for Strings as a convenience because of the frequency with which Strings are used.(That’s why they can seem like primitives – but they are not.)
Three obvious String support features:
1. You need not explicitly instantiate Strings with the ‘new’ keyword.
Java automatically instantiates a String object when it encounters a text string within double-quotes.
For example . . .
Strings vis-a-vis ObjectsStrings vis-a-vis ObjectsAssignment w/References to Strings/Objects: Code: Memory:
String str1;Box box1;
str1box1
str2 = “Glib Folksies”; str2
Glib Folksies
?default?
str1 = “Hello World”;box1 = new Box(iLn, iWd, iHt);
Hello World str1box1 iLn, iWd, iHt
str1 = “Hello World”;
box1 = iLn, iWd, iHt;
Hello World str1box1
ERROR: must use new “new” and call constructorERROR: must use new “new” and call constructor
str2 ?default?str2 = new String();
Important DigressionImportant DigressionGiven:String s = new String();
How can we be sure of the default behavior?
Remember that thing - the API? Download it!(http://www.javasoft.com/docs)
1. Go to class String2. Click on constructors3. Look for the default one and read
it’s documentation4. Mystery solved!
Now back to the show…..
Strings vis-a-vis ObjectsStrings vis-a-vis Objects
Again, Java automatically creates a new String object whenever it encounters text within double-quote marks.
Thus, the code:
String str1 = “Hello World”;
accomplishes three things:
1. It creates str1 as a reference to a String. 2. It creates an instance of a String. 3. It initializes that String to “Hello World”.
This is inconsistent with how Java treats standard objects.
With standard objects, you must explicitly: instantiate (via new), and initialize (via a constructor).
3. Several predefined methods provided in built-in class String. Among them are:
length( ) // a string knows its length – note it is a method! charAt(iIndex) // returns letter at position iIndex; 1st char is position 0 substring(iStartIndex) // returns the substring fromposition
// iStartIndex to end of string substring(iStartIndex, iEndIndex) // returns substring from position
// iStartIndex until but NOT INCLUDING position iEndIndex
Three obvious String support features:
1. You need not explicitly instantiate Strings.
String StuffString Stuff
continued
2. The ‘+’ operater overloaded for Strings, to support concatenation, e.g.,
System.out.println(“This string is an example of” + “ one that is too long to fit on one line. Your TAs take off points” + “ for lines that exceed 80 column characters.”);
String Stuff -- ExamplesString Stuff -- Examples
H e l l o0 1 2 3 4
char c = strExample.charAt(1); // c gets ‘e’
String strBritishHowdy = strExample.substring(1);
strBritishHowdy ---> “ello”
String strTemperatureOutside = strExample.substring(0, 4);
strTemperatureOutside --> “Hell”
String strExample = “Hello”;
Also . . .
One cannot change contents of a String object. (We say: “Strings are immutable”.)
You may think you are modifying a String. But, what happensin memory is:
1. a new String is created2. you change the String reference to refer to that new one3. your old String may be ‘garbage collected’; you no longer have a reference to the old String
For example:Hello World str1String str1 = “Hello World”
str1 = str1.substring(4)
Hello World
o World
str1
Optional: see class StringBuffer for ways to work around this limitation.
Strings vis-a-vis ObjectsStrings vis-a-vis Objects
Objects and References: The special case of StringObjects and References: The special case of StringCaution: In the next few slides, we will cover what is one of the more confusing parts of Java for CENG217 students. If you get lost, just remember what we’ve covered so far:
1. When comparing primitives (int, float, etc.), use ‘==‘ 1. When comparing primitives (int, float, etc.), use ‘==‘
2. When comparing objects (String, or any class you create), 2. When comparing objects (String, or any class you create), use the equals() method. use the equals() method.
3. When you create a class that serves as a data type or 3. When you create a class that serves as a data type or record, remember to include an equals() method.record, remember to include an equals() method.
In the slides ahead we will note some rare exceptions where the ‘==‘ comparison will work for objects. (Yes, you can use == to compare objects, but not in all circumstances!)
When in doubt, please just follow the principles above.
Objects and References: Review of the normal case
Remember the general pattern of our previous example:box1 = new Box(1, 2, 3);box2 = new Box(8, 5, 7);box1 = box2;System.out.println(box1 == box2); // prints true// Does box1 reference the same object that box2 references?
System.out.println(box1.equals(box2)); // prints true// Does box1 reference an object that has the same contents// as the object referenced by box2?
box1 box2
L=8, W=5, H=7
L=1, W=2, H=3memory
Hello
Hello
As part of the Java Language Specification (the ‘rules’ for the Java Language), Strings have a special characteristic. It turns out that in some circumstance (BUT NOT ALL), you can use ‘==‘ to compare Strings, in addition to .equals(). Consider:
String strHello1 = “Hello”;String strHello2 = “Hello”;
We would expect these lines to produce the following memory changes
In fact, it produces the following results in memory:
strHello1strHello2
HellostrHello1strHello2
Equality with References to Objects:Strings are special
Huh? Why are Strings treated differently?
Strings are sometimes a special case of equivalency in Java. When the compiler encounters the lines:
String strHello1 = “Hello”;String strHello2 = “Hello”;
the compiler is smart enough to know that the two Strings are identical. So, it decides it will save a few bytes of memory and point to the same location in memory. The same result would occur even if you wrote:
String strHello2 = “Hell” + “o”;
This means that for the above lines of code, equals() and ‘==‘ both work:
System.out.println (strHello1.equals(strHello2)); // trueSystem.out.println (strHello1 == strHello2); // also true, but
// dangerous . . .
Exception to the exception with String
But this special case for ‘==‘ comparison of Strings DOES NOT ALWAYS WORK . . .
Consider: If one of the Strings were created with use of the ‘new’ keyword, the two Strings would no longer share memory. (That is, ‘==‘ would be false, but equals() would still be true, if the contents of the Strings are the same.)
So, there’s an exception to the exception for Strings when you don’t use the String exception to object instantiation. Confusing? Exceptionally so!
LESSON: DON’T USE THE EXCEPTION. Don’t compare Strings, or any Object, with ‘==‘, even if you think the exception will apply.
REMEMBER: Just compare primitives with ‘==‘, Objects, including Strings, with equals() -- and it always works fine!
toString()toString()or not to String...or not to String...
Debugging:
Debugging StrategiesDebugging StrategiesIncremental Programming:
The Idea: Find and repair bugs “in the small” before you have a program with several components. The hardest thing is finding the errors. So, find them as you create each class.
Thus, do not:• write your entire program, then• type in your entire program, then• attempt to test your entire program
Instead:• design your program at high level, then• focus on one class at a time,• for each class, write and test before going on to the next one.
This way, you deal with bugs when it‘s easiest!
Debugging StrategiesDebugging StrategiesPotential problems with state objects: State incorrectly modified by modifer methods. State incorrectly represented by accessor methods.
Need: A way to see the state of the object.
Means: public String toString ( )
• Create one “toString” method per class.
• Now we can use a reference to an object directly as an argument in:
System.out.println ( );
Example of using toString:
If we have a method for Class Box:
public String toString ( ) {
String returnStr; returnStr = new String(“Box: length = “ + iLength +
“, Width = “ + iWidth + “height = “ + iHeight); return (returnStr);
} // of toString
Then we can do: Box subwooferBox = new Box(40, 50, 60); … System.out.println ( subwooferBox ); // what???????? // wait a minute where was the call to “toString”????
Debugging StrategiesDebugging Strategies
Special invocation of toString methodSpecial invocation of toString method
• Using an object reference when a String is needed will implicitly invoke the object’s toString method. Bonus!
• This is why it is critical that you actually provide a meaningful toString method for practically every class you create.
• Excellent for debugging!
Debugging StrategiesDebugging StrategiesOne “main” per Class
• According to Java, you only need one main per program. . . not one per class.
• But Java doesn’t know how to program!
• To test/debug a class, create a main method for the class as part of the class . . .
• Include in “test mains” the: declaration of variables the invocation of methods the generation of output (e.g. using toString())
that will allow you to see what the class actually does!
• Then, invoke the main as part of your testing process.
• The main can stay there as part of your class . . . invoked only when you call it for purpose of testing.
What?What?Suppose you have class A, class B, and class C; each has a main method for debugging purposes.
Class C has the real main for your overall program, and uses classes A & B.
How can you invoke a particular main?
javac A.java <- compile class Ajava A <- invokes A’s main for testing Ajavac B.java <- compile class Bjava B <- invokes B’s main for testing Bjavac C.java < compile class Cjava C <- invokes C’s main
Debugging StrategiesDebugging Strategies
• Define a boolean constant in every class called DEBUG
public static final boolean DEBUG = true;
• Wherever appropriate insert...if(DEBUG)
System.out.println("method>var = "+var);
• Customize as necessary!
Questions?Questions?