I'll tune you into one convention Java folks use - class names start with a capital letter. I'll use that in the rest of this note ...
Have you tried compiling to see what messages you get? If you're not even there yet, make a file for each class with filename exactly matching the class name, even the mixed case: Test.java, Dog.java, Cat.java.
Creating a new Dog and calling woof() look ok. I'm betting the compiler says the symbol "fluffy" is not recognized in your Test class. If you comment out that line it might well run and say "Woof".
So, what about fluffy? You declared the variable inside the Dog constructor. That gives is "local" lifespan and visibility, meaning it can only be accessed by the code in the constructor, and becomes eligible for garbage collection when the constructor exits. So by the time you get to "fluffy.meow()" the object is already out of sight.
To fix that, we can make fluffy a "member variable" in Dog. Dog looks more like:
Now the fluffy object will last as long as the Dog object. But the Test object still knows nothing about the fluffy variable. Only Dog has that variable. We could modify Test like this:
See if that works for you. Then we can talk about better designs that "hide" fluffy from Test.
A good question is never answered. It is not a bolt to be tightened into place but a seed to be planted and to bear more seed toward the hope of greening the landscape of the idea. John Ciardi
Joined: Jun 18, 2005
Wow, thanks for the quick reply!
OK I renamed all the files and re-compiled. The original error messge you predicted was spot on. I didnt realise the reference to Cat was limited to only the constructor.
I added the code you suggested and it compiles, I get the output "Woof" as expected but the program throws a NullPointerException at
As for your better ways of doing things, I'm all ears.
You must not have copied Stan's version of the constructor exactly. Most likely you didn't change it at all. That means it's still your local variable named fluffy, and not the member variable, that's getting initialized. Look carefully at Stan's constructor, and see how it's different from yours.
Well, I can briefly explain it here, but any decent introductory Java book is going to explain this early.
A variable's scope, or availability, depends on where it's declared. If you declare it in the class, then it lasts as long as the object does, and all the methods of the class can share it. But if it's defined in a constructor or method, then it's available only in that constructor.
If you say "Cat fluffy = new Cat();", or more generally, "type name = something;", then you're declaring a variable and assigning it a value. If, on the other hand, you're saying "name = something;", then you're referring to a variable that already exists.
If you declare a variable in one scope, and then declare another one by the same name in a "smaller" scope, then that second one effectively hides the first one for code in that smaller scope. I.e., if you declare a "fluffy" at class level, and then another "fluffy" in the constructor, then the member variable at class scope is ignored in the constructor. Here, that causes the member variable to never get an assigned value -- i.e., to remain null.
Does this make sense?
Joined: Jun 18, 2005
I've read that before and it didnt make sense but it does the way you explained it.
Thanks guys, sorry for the tedious questions but you really helped.