|
home—info—exams—lectures—labs—hws
Recipe—Laws—lies—syntax—java.lang docs—java.util docs
We have seen that java has the primitive types int, long, double, boolean, and char (along with the less-precise numbers: byte, short, float). For each1 of these primitive types, Java also provides a corresponding wrapper class: Integer2, Long, Double, Boolean, and Character, (along with Byte, Short, and Float).
For example, an instance of Double is just an object which contains one lonely field -- a field of type (you guessed it) double.
// Draw picture: double d1; d1 = 12.3; Double dd1; dd1 = new Double(12.3); Double dd2 = new Double( 12.3 ); Double dd3 = new Double( d1 ); Double dd4 = dd1; dd1.toString() dd1.doubleValue() dd1.intValue() d1 = 45.6; dd3.doubleValue(); // Could dd3's value change, from modifying d1? // If you weren't sure, re-read last week's notes dd3 = dd2; dd1 == dd3 // true or false? Try it out! Your picture should explain. dd1.equals(dd3); // true or false? Try it out! Your picture should explain. dd2 == dd3 // true or false? Try it out! Your picture should explain. dd2.equals(dd3); // true or false? Try it out! Your picture should explain. |
Why do entire classes even exist, when we already have the primitive types, which work just fine? Good question. The reasons why these wrapper classes exist are:
Just to keep things from looking simple (even though they are), Java, as a favor, silently converts between primitive types and the wrapper classes:
dd1 = 3.4; // "auto-boxing" -- same as: dd1 = new Double(3.4); dd1 + d1 // "auto-unboxing" -- same as: dd1.doubleValue() + d1 dd1 + dd2 // Does this mean auto-unboxing, or string-concatenation?!?! dd1 == dd2 // Does this compare-objects, or unbox-and-then-compare-numbers?!?! |
Let's look at the hw05 solution documentation.
We realize that some of the methods were simply helper functions for our own code. The method getMinutes (which returns a NumberDisplay) is not really meant for our clients to call. Similarly, wrap1_12 is our own internal function which is just a helper for getTime12. On the other hand, getTime12 and getTime24 and timeTick and setTime are what we want our clients to call.
We can make these assumptions clear: every field and method can be labeled with an adjective public or private:
A public method (or field) can be called by any other class.
In our example, ClockDisplay's getTime24 should be public, because our whole purpose is to let people ask what time it is. timeTick also needs to be public, since we rely on other people to tell us each time has passed. What other methods should be public?
In PizzaServer, work and tip would all be public. On the other hand, spend and addToBalance probably aren't public -- those are actions which the PizzaServer might choose to do itself, but can't be initiated by EmCees or Dogs.
In particular, constructors are usually public!
A private method (or field) can only be called from within that same class (the same file).
That is, if PizzaServer's getBalance() is private, then that method can only be called by PizzaServers. A PizzaServer can call its own getBalance() (which it needs to do from inside addToBalance(), which might be public). This is perfectly reasonable.
In addition, a PizzaServer can also call getBalance on any other PizzaServer that it happens knows about. (For example, the following fragment works just fine:
public class PizzaServer { // comment omitted... private getSalary() { /* body omitted */ } // comment omitted... private hasHigherSalary( PizzaServer other ) { // It's legal for one PizzaServer to call another's private method. return (this.getSalary() > other.getSalary()); } } |
In our example, ClockDisplay's getTime24 should be public, because our whole purpose is tell people the time. Similarly, timeTick needs to be public. But getHours (which returns a NumberDisplay) should be private: its purpose is to access internal state, which is in a format/class whose details might change in the future. What other methods should be private?
What this means for us: From now on, every method and field should be declared either public or private.
Rule of thumb: If you modify an object's internal implementation, you should not need to change any of the public signatures.For example, if we modify ClockDisplay to have only one field int minutesSinceMidnight, others will still call getTime24 just the same as before. But if they'd been calling getHours (which returns a NumberDisplay), suddenly this our internal modification would break their code, oops! The problem is that really, they should not have been calling getHours anyway. By making that getter private, we ensure that nobody else could be calling it.
(Only code which dealt with non-public methods should have to worry about the new implementation.)
1There is also class Void, which technically isn't a wrapper class because there aren't any void values to wrap! ↩
2Integer and Character are the two wrapper classes whose name isn't quite just the capitalized version of its corresponding primitive. ↩
3A minor lie:
it really rewrites it as
Double.toString(3.0) + " blind mice",
but we haven't yet discussed static methods.
And actually, I'm not sure whether the java compiler is
required (or allowed or disallowed) to optimize early,
and
convert the literal 3.0 into
a String at compile time
(perhaps even doing the concatenation right then, too?).
↩
In fact, you might wonder if there is some “very-private” modifier which means “The method/field can only be accessed by this object itself”. Java does not have such a concept.
While such a protection-level is a very common design goal, and it makes sense from a pure object-oriented mindset, Java's philosophy is that if a programmer wants to violate privacy expecatations between PizzaServer, and that programmer has access to the source code for class PizzaServer, then that programmer could always do so: they'd just change the modifier from “very-private” to merely private.
If you ever design your own language though, it's worth not taking this for granted. Many features in programs are there to help protect programmers from themselves. (Declaring types in advance is one such feature.)
↩home—info—exams—lectures—labs—hws
Recipe—Laws—lies—syntax—java.lang docs—java.util docs
©2007, Ian Barland, Radford University Last modified 2007.Aug.27 (Mon) |
Please mail any suggestions (incl. typos, broken links) to ibarlandradford.edu |