Franz Fountain

Ranch Hand
+ Follow
since Nov 15, 2006
Merit badge: grant badges
For More
Cows and Likes
Cows
Total received
0
In last 30 days
0
Total given
0
Likes
Total received
0
Received in last 30 days
0
Total given
0
Given in last 30 days
0
Forums and Threads
Scavenger Hunt
expand Ranch Hand Scavenger Hunt
expand Greenhorn Scavenger Hunt

Recent posts by Franz Fountain

Hi Wes,

Yes. That's it.

Cheers,
Franz
Excellent Wes

Here are some scattered thoughts in reply.

I think there is a subtlety in that the compiler always acts as if there is no overriding in effect in determining whether a method is valid or not. Only methods of the reference type are allowed to compile.

I don't know if a private method causes the compiler to create optimized code that does not allow polymorphism (overriding). In C++ you actually have to mark a method as "virtual" in order to get polymorphism. In Java polymorphism is ON by default. The reason for the C++ decision is that polymorphism has a negative performance effect and C++ is less OO (Object Oriented) in this respect. So I don't know if the compiler optimizes the code at compile time or if the JVM realizes at runtime that the method is private and then does the right thing.

Regarding overloading, there is a kind of "poly-something" going on. It's a static choice of methods based on the parameters. It's not as whizbang as runtime polymorphism which is a dynamic choice of methods, but it's still an interesting feature of the language and not trivial.

Prabhu makes a very good and interesting point in saying that the drink() method is neither overriden nor overloaded by Horse. It is simply a new method with the same name as the method in Animal. It could have been called eat() and the effect would be the same. There is no relationship between the 2 drink methods of Animal and Horse because of the private label in Animal. This is because Horse never sees the drink method at all and is completely unaware that such a method even exists. The drink() method in Animal is totally hidden from view by the private access modifier. It's so hidden that the compiler is fooled into thinking that Horse just came up with the drink() method name all on it's own. I'm actually surprised that this doesn't produce an error or at least a warning, but there is no complaint at all from the compiler.

I also asked a question "what access modifier would you use to create a method that can be inherited by any subclass but can't be seen by any other classes?" Prabhu said protected, but I disagree. A protected method is visible to any class in the package. In fact protected is less restrictive than the default access modifier (which is sometimes called "friendly", but I prefer to call it package access.) Protected just adds "subclasses that are not in the package" to the list of classes that can see a method (or variable). The answer is that there is no such access modifier. My best guess if I didn't know anything about Java or OOP would be that "private" would be the access modifier that would answer the question. But as we've learned, private is very restrictive. (In C++ protected would be the correct answer because C++ doesn't have the concept of package.)

You know there's still another issue lurking in this example.

Why does the horse refuse to drink private water? Why is the output "Animal doesn't drink private water" instead of "Animal drinks private water"? After all the Horse is at the water, why not drink?

(I have a feeling I've missed something important in my reply but I can't think of what it is. Oh well I suppose someone will point it out.)
Hi Prabhu,

Looks like you already understand this question. You get the free Pony ride!
weee

Franz
Hi Wes,

In your first reply you said


Animal can't call a Horse method, even if it's overridden in Horse.



I think you meant
Animal can't call a Horse method, unless it's overridden in Horse.

We're exploring polymorphism here and polymorphism requires that a method be overriden. It also requires that a superclass reference variable be used to refer to a subclass object. That's why Horse is assigned to an Animal reference variable.

In your second reply you said


Oops, I was wrong in my last post. If you change the private drink() method in Animal to public, it does call the public drink() method in Horse. So, perhaps, since the method in Animal was marked private, the Horse class did not have access to it, and could not override it.



Yes the drink() method in Animal is marked private. So does the Horse class have access to it? That's the question. If Horse doesn't have access, then can it override drink()?

On to your third reply


Are the drink() methods considered overloads? (I don't think so)

The reason I ask is because they act just like overloads in the situations I've tested them in. They use the reference type to determine which drink()method to run. When drink() is called in Animal, the only way it can execute the Horse drink() method is to use a Horse type reference variable, or a reference variable that is cast to a Horse type.



So is the drink() method in Horse an override or an overload of the drink method in Animal? That's the essential question here. It has the same signature (same name, same parameters, same return type) so it looks like a valid override. But, oops, the same method in Animal is marked private.

As you have seen through your experimentation, the drink() method in Horse acts like an overload. The reason has to do with the private nature of the Animal drink() method. Look at K&B Ch. 2 p. 102-103 for rules on overriding. What does it say about private methods?

Here is your experiment which does indeed simplify part of the original question.


class Animal {
private void drink() {
System.out.println("Animal drinks");
}
public void calldrink(Animal a) { //1-Change Animal to Horse - try it,
a.drink(); // 2-then cast a to Animal <((Horse)a).drink()>, try it.
}
}

class Horse extends Animal {
public void drink() {
System.out.println("Horse drinks");
}
}

class Test2 {
public static void main(String[] args) {
Horse a = new Horse();
a.calldrink(a);
}
}



The questions I have for you regarding line 2 above are:
What method does the compiler think is being called?
and
What method does the JVM think is being called (at runtime)?
and
How do these differ for overriding (when polymorphism is in effect) and overloading?
and finally
Is there any polymorphism associated with overloading?

These are big OO questions and the model you use in your brain to visualize overriding and overloading will determine your answers. In my case I found that my model needed a bit of tweaking when I looked at this rather simple "Horse drink" code.
Hi Greg and let me be the first to welcome you to Javaranch!

Now to your questions.


1.) Do the below lines create two instances on the heap, one for the horse and one for the animal?
code:
class Horse extends Animal

// class header and main method
Animal a = new Horse();
// close main and class



This creates an Object/Instance of a Horse (on the heap) but it does also create a Animal reference variable (on the stack). The reference variable is assigned to refer to the Horse object.


3.) If you change the drink method in Horse to private the cast of animal to horse doesn't work. Why is that, don't you get don't you get the private methods of the original class? Through testing it does not appear that way but I'm not sure why.



I'm not sure what you mean by "the cast of animal to horse doesn't work". As to the other question "Why is that, don't you get don't you get the private methods of the original class?", this is the big question that is being explored here. Take a closer look at the access modifiers and there definitions in Ch. 1 of K&B (Kathy Sierra and Bert Bates book). On p. 30 it says a subclass can't inherit a private member. So that includes methods.

In this case drink() is a private method of Animal, so it can't be inherited by Horse.

By the way, what access modifier would you use to create a method that can be inherited by any subclass but can't be seen by any other classes?
What is it about horses? You can lead them to water, but you can't make them drink!

Take a look at this code for example:



And now I'm going to show you the output

Horse eats
Horse doesn't drink packaged water
Horse at water
Animal drinks protected water
Animal doesn't drink private water


The horse is at the water, but it won't drink the water. Why?
Hint: Take a look at line #1.

For all you ranchhands - what happens when you untie your horse at line #2 and give him/her another chance to drink?

The winner gets a free Pony Ride! Wheeee!
[ November 26, 2006: Message edited by: Franz Fountain ]
It's quite common to see code like:
List<String> myList = new ArrayList<String>();

My question is why not just do:
ArrayList<String> myList = new ArrayList<String>();


I don't see the advantage of using polymorphism in this case. I guess ArrayList doesn't have any methods that are not in the interface List or this would really cramp your style. Is the advantage because now if you want to change your implementation and use a LinkedList instead of an ArrayList that you can easily do that in one line? I don't think that's a very good reason and I haven't found any other.
Hi Satish,

Thank you very much. That's very interesting. So PRESENT is a constant object. I assume at retrieval time if Object == PRESENT, then the Key is returned as the Value.

Is that right? Anyway, you've answered my original question. The rest is just implementation details. Still it's very interesting to see how it's implemented. It's great that Sun releases the source code unlike Microsoft. Actually if you've ever seen any MS source code (they do release some), it's unbelievably convoluted. Sun sources seem to be so much clearer and easier to read. Just a different culture I guess. Go Java!
K&B p. 557 4th bullet
"which is passed as the second argument to the binarySearch() method."
s/b
"which is passed as the third argument to the binarySearch() method."

In other words the Comparator is the 3rd argument to binarySearch() not the 2nd. See example on same page at "#5".
So your saying HashSet is really using HashMap under the covers. So does this mean that the [key, value] pair is a same to same relationship. For example in the case of a set of Strings:

Key Value
"apple" "apple"
"grape" "grape"
"cherry" "cherry"

Is that the way it works?

[ November 22, 2006: Message edited by: Franz Fountain ]
[ November 22, 2006: Message edited by: Franz Fountain ]
OK. I'll come up with a few examples and add them to this topic.

I have a friend that judges technical books by the size of their index. He tends to by the one with the largest index. I guess he wouldn't like the Head First series. :roll:

I'm actually looking forward to reading the Head First Patterns book after I pass the SCJP.

Bert and Kathy, you rock!
I looked at the section you mentioned in K&B. It talks about hashcodes. I understand hashcodes and I understand sets. I just don't understand what hashcodes have to do with sets. This is not explained explicitly in K&B.


But anyway back to the question. I understand how hashcodes and maps work together. This is the obvious use of hashcodes to store and retrieve information with good performance.

The not so obvious one is sets. Sets are collections of unique objects. A TreeSet makes sense to me. Since the tree is maintained in order, there can be a search for an element and if it matches then it isn't added to the TreeSet.

A HashSet doesn't say how the set is stored which seems important. Is it an array or linked list or a tree? I don't know. It just feels very fuzzy to me. Does anyone have any more concrete information regarding HashSets?

Thanks
Hi Matthew,

I suggest looking at the "Chew on this!" thread. I have a similar question.

Franz
So the answer is?

I think it's B1 gets unboxed to a byte and then promoted to a int for the comparison with the int literal 5.

Am I right?
[ November 21, 2006: Message edited by: Franz Fountain ]
Think of it this way... studying for SCJP will help prepare you for your next interview. I can't imagine an interviewer coming up with trickier questions than are on the SCJP. In fact I can't imagine any trickier programming questions than the SCJP questions.

Seriously, has your boss ever taken the SCJP? Is he a programmer? Challenge some of your co-workers to answer some of the mock exam questions. My guess is even experienced Java programmers will not be able to pass the exam without 2 weeks preparation. You have my sympathy. I guess I would go with the re-negotiation strategy described by others.

I do believe that studying for the SCJP has inherent value and will make you a better programmer. When you're done you will understand the language better and have more confidence in yourself.