Wow! This is what I get for sleeping in this morning; a really fun pile of posts here today.
Before I answer this next one, I just want to say that Bert and I can completely relate to the frustrations of trying to learn from books that make too many assumptions about what you already know. Or they don't include any pictures. Although I must say that *now*, having done both the Head First book and our certification book, I understand why so few books have pictures -- when we did the certification book, we were forced (as just about any technical book author IS) to use their templates, and the process of getting diagrams and illustrations in is VERY difficult and error-prone. And you do not always get to specify even *where* the pictures will actually go.
In contrast, with the Head First book, O'Reilly let us build each page by hand, so we made pictures in much the same way that I would sketch on a white board (or a napkin, over a few drinks... doesn't *everyone* discuss polymorphism at the pub?

) In other words, we drew or pasted pictures, directly into the actual page that you see. O'Reilly let us -- encouraged us -- to build the book exactly the way it needed to be built for *learners*. But most authors are forced into building a book for the benefit of the publisher's process.
Originally posted by R Mera Naam:
Is there some easy way (apart from reading your book, I assume) to understand...
No. Without our book, there is only the slow, painful, torturous way.
I'll try to give a little summary
1) public vs. private
'public' is for the things you want to expose to everyone else's code. If you are making re-usable classes (which of course, good OO programmer that you are, you are doing), the 'public' methods are the reason you created the class in the first place: so that others can take advantage of the functionality you built into your class. In other words, the things your objects can DO.
'private' is for what your class needs to use internally, but that you don't want others to access.
The simplest -- and most important example -- is to use public and private to implement good 'encapsulation'. This is where you protect your *data* (i.e. your instance variables) and force everyone else to go through methods to access the data.
Easy way to do this:
* Mark your instance variables PRIVATE
* Create PUBLIC getters and setters
Why? What happens if you have the Cat class, for your animal simulation program, and it looks like this:
This is an example of a well-encapsulated class, because you have protected the data (the size instance variable) through methods.
Now, if you look at the way it is NOW, it looks like you have saved *nothing* and instead just added more overhead to getting and setting the Cat size.
But look at what this lets you do:
public void setSize(int s) {
// validate the size -- in other words, make sure
// the size is appropriate
if (s >= 0) {
// size is acceptable
size = s;
} else {
// NO! Can't have a zero-sized Cat!
// don't do it
}
}
If you allow someone to change the size without going through your method, they could do something awful -- like make a zero-sized cat. Or worse... a NEGATIVE-sized cat. (Something I *wish* would happen to my cat).
Most importantly, marking your variables private and forcing everyone to go through methods gives you another HUGE benefit of OO -- The ability to CHANGE YOUR MIND later. Flexibility, extensibility, maintainability are all made possible or greatly improved by using encapsulation.
Because look at what would happen if you didn't do this... you make a Cat class, and you let everyone step all over the data:
public class Cat {
public int size;
// other stuff
}
Now everyone else writes their code to directly access the size.
After a few weeks, you realize this is a problem (it didn't occur to you that anyone would accidentally or on purpose try to make a zero-sized cat...)
So you decide to fix it by marking the data private and adding public getters and setters so that you can validate the data.
And now look what you have done -- broken everyone else's code! Anyone who was using your class must change their code! And nobody wants to do that.
The bottom line is that if you protect your data, by marking instance variables private and providing more accessible (i.e. public) methods to access the data, you have the flexibility to go back and change and improve your methods, without hurting anyone else's code.
But there is a lot more to public and private, and of course there are the other modifiers as well.
You might want to mark METHODS as private, because they are methods that *your* own methods can call, from within your class, but you do not want anyone else to be able to call. For example;
Here we use a public constructor, but inside the public constructor we call our own *private* method. We don't want anyone else to access the 'assignNewID' method because it does critical things, including access a database. So private methods are for functionality that our own class needs, but that would be dangerous for anyone else to access. It is security to mark it private.
You can go a LONG way without having to use the other two access levels 'default' (what you get when you do not specify private, public, or protected) and 'protected' -- which most developers almost NEVER use.)
==================
2) Static vs. non-static methods
This one is easy: Java is an OO language. OO is good, for a million reasons, so
you should assume that almost everything you make will NOT be static. If you make your methods static, you are hurting your ability -- permanently -- to have those methods be specific to a particular object. So the best rule is to assume NOTHING is going to be static. And then only if you see a very strong need, should you mark something static.
Non-static methods, remember, can use the instance variables of the object that was used to invoke the method.
public void bark() {
if (dogSize > 5) {
doBigBark();
} else {
doSmallBark();
}
}
In this code, the method must use an instance variable - the value of 'dogSize', in order to perform the appropriate bark.
If the method were static, it could not use any individual dog's value, and would have to bark the same way for every dog.
It is a lot like the argument for why you should use public getters and setters -- you can change your mind later without breaking anyone else's code! If you make a method static, you cannot later decide that maybe it *should* be an instance method.
But if you make everything an instance method, you can change your mind later.
So why ever use static for a method?
Because sometimes -- but RARELY -- you have a 'utitlity' method where there is NO question that it will always run exactly the same way. This is how java.lang.Math package works. A method that takes a number and returns the absolute value, for example, will NEVER change for different instances of the Math class.
But this is a special case. Do NOT make the mistake of thinking that static methods give you a performance benefit. Well, they actually *do* give you a tiny performance gain over non-static methods, but it is almost NEVER worth it for what you lose in flexibility, extensibility. If you make something static, you have made a permanent decision. If you make something an instance method instead, you are leaving yourself the freedom.
Static variables are a little different. Use 'static' when you have a variable that MUST be shared by all instances of a certain class. If you want to count the number of Cats being created, then you want ONE variable that does not get reset for each new Cat (as an instance variable would), but instead be the same for EVERY Cat.
public class Cat {
private static int catCount;
public Cat() {
catCount = catCount + 1;
}
}
OK, that's the short version of using static.
======================
FINAL:
final means slightly different things, depending on what it is marking:
1) FINAL CLASS
-- means the class cannot be extended / subclassed
Why use it? Don't use it very often! Again, you have hurt your extensibility (killed it, actually) if you make a final class. But sometimes, for security, you need to, because you must guarantee that a class always works the same way -- the way you wrote it. That's how the
String class in Java works, for example.
2) FINAL VARIABLE
-- means that once the variable is given a value, you can never reassign the variable. In other words, if the size is set to 5, it can never be changed to 6 or 10 or 4,000.
CONFUSION: if the value of the variable is a reference to an object, a final variable does NOT mean that the object itself is final. If you have a final 'remote control', it means that you cannot ever "reprogram" that remote control to a different object. In other words, the programming of the remote control is what cannot be changed. But you can still USE the remote control to change the object itself (change channels, colors, sound, etc.)
final Dog d = new Dog();
// now I cannot ever do this:
d = new Dog(); // NO
d = null; // NO
d.setName("Neo"); // FINE
3) FINAL METHOD
-- means the method must not ever be overridden by a subclass. So, if a class if marked final, it means that all of it's methods are automatically final. But you might have a class that you DO want to subclass, but which has one or more methods which you do not want overridden. In this case, mark the method final but leave the class NOT-final.
Why make a method final? Again, for security. When you absolutely must guarantee that no subclass can sneak in and make their own version of the method (which, because of polymorphism will run whether you planned on it or not), then mark the method final.
CAUTION: use 'final' with a lot of caution for methods and classes! It can really hurt your OO. But when it is needed, use it. A 'final' variable has such a different purpose, that it usually does not hurt your OO to use it.
last thing...
PUBLIC STATIC FINAL VARIABLE
-- this is how you do a 'constant' in Java.
The value of Math.pi is a constant.
If you have something that must never change, and is always the same for any object of any class, then make it a public static final variable.
======================
Warning: I have really simplified things here; there are -- as always -- lots of exceptions to these rules, but they are enough to get you started on a good OO path.
Cheers,
Kathy
(whew! that was NOT a tidy little question

)