Caroline Bogart

Greenhorn
+ Follow
since Nov 21, 2001
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 Caroline Bogart

My friends, I feel I am close to getting this but that words are getting in my way.
Jose wrote:
<quote>

TypeOfTheReference reference =
new ClassOfTheCurrentObject();
reference.methodDeclaredInTypeOfTheReference();
</quote>
Khalid (p.181) says:
<quote>

When a method is invoked on an object using a reference, it is the class of the current object denoted by the reference, not the type of the reference that determines which method implementation will be executed.
</quote> (emphasis added)

Which part below, then, is wrong?
The "current object" is the operand being assigned to a reference
The "reference" is the operand receiving the assignment.
The "class of the current object denoted by the reference" is:
(a) the current object's class (being assigned)
ObjType objType = new SubType()
(b) the current reference's class (receiving assignment)
ObjType objType = new SubType()

Because I know that assigning a subclass to a superclass reference reduces that references ability to "see" superclass behavior, the answer must be that the "class of the current object denoted by the reference" is the right hand operand.
My problem is probably with the word "denoted." When something is "denoted by the reference," the reference rules the day.
Excuse me for being so dense, and thanks again,
Caroline

------------------
I love JavaRanch!

[This message has been edited by Caroline Bogart (edited December 02, 2001).]
Uma,
I thank you for your patience, but you will now see why I remain confused.
In my original example, it is the type of the reference, not the type of the object that is determining method invocation.
In that example there are 5 references. Each reference is assigned the object of the type SafeStackImpl.
The reference types are:
SafeStackImpl
StackImpl
ISafeStack
IStack
Object
When a reference of type SafeStackImpl receives an object of type SafeStackImpl, the invokable methods run all the way up the heirarchy. This reference can invoke push, pop, peek, isEmpty and isFull.
When a reference of type StackImpl receives an object of type SafeStackImpl, the invokable methods are: push, pop, peek.
When a reference of type ISafeStack receives an object of type SafeStackImpl, the invokable methods are: push, pop, isEmpty, isFull.
When a reference of type IStack receives an object of type SafeStackImpl, the invokable methods are: push, pop.
And, finally, when a reference of type Object receives an object of type SafeStackImpl, the invokable methods are only those known to the Object class (such as getClass()).
Every time the object class on the right side of the assignment reduces accessibility to the inheritance tree, the pool of invokable methods is reduced. What's changing is the class of the object, not the type of the reference.
<PRE>
_______________ _______________
|<<interface>>| | Object |
| IStack | |_____________|
|_____________| |_____________|
|_____________| | |
| push( | | getClass() |
| pop() | |_____________|
|_____________| ^
^ ^ |
| |_ _ _ implements _ extends
extends | |
| | |
_______________ ________________
|<<interface>>| | StackImpl |
|ISafeStack | |______________|
|_____________| |______________|
|_____________| | push() |
| isFull() | | pop() |
| isEmpty() | | peek() |
|_____________| |______________|
^ ^
| |
- - - - - - - ______|
| |
________________
| SafeStackImpl |
|_______________|
|_______________|
| |
| isFull() |
| isEmpty() |
|_______________|
</pre>
A reference of type SafeStackImpl has access to the entire tree's worth of methods because, it appears, it is assign an object of type SafeStackImpl.
A reference of type SafeStackImpl has access only to the methods of the type Object, if it is assign an object of the class Object.
The right hand side, the class of the object, not the reference type, is determine what is accessible.
Thank you again in helping me with this confusion,
Caroline

[This message has been edited by Caroline Bogart (edited November 30, 2001).]
[This message has been edited by Marilyn deQueiroz (edited November 30, 2001).]
Great post.
Maybe I'm getting old, but I find the CODE tag impossible to read (and I don't even have those half glasses yet!).
So I do this when posting code, hope all will follow to make the site easier to read:
<CODE>
Blue code, size 3!!
I'm pretty happy with the legibility!
</CODE>
This is simply <CODE><FONT COLOR=blue size=3>
your code here
</FONT><CODE>

------------------
I love JavaRanch!
Actually, no, though I appreciate the effort.
I just want to define some terms.
After this quote, I will ask to define terms from the quote. That is my actual question:
Khalid, p 181

When a method is invoked on an object using a reference, it is the class of the current object denoted by the reference, not the type of the reference, that determines which method implementation will be executed.

What is the definition of:
1. reference
2. class of the current object
3. type of the reference
Thanks again,
Caroline

Originally posted by Uma Viswanathan:
Let us take the simple example...
interface IStack {
void push();
void pop();
}
class StackImpl implements IStack {
public void push() {System.out.println("push");}
public void pop() {}
public void peek() {}
}
class StackUser1 {
public static void main(String args[]) {
new StackUser1();
}
public StackUser1() {
IStack istackRef = new StackImpl(); //according to //conversion rule, this is valid
istackRef.push(); //compiler knows that the type of //istackRef is only IStack and checks whether push //is in IStack. Exists and so, no problem
istackRef.peek(); //peek does not exist is in IStack. So, //compile time error
}
}
Read the explanation in the comment (i.e, after //)
If you override the method, then only at run time, we need to consider the run time type of the object.
Hope this helps...
Uma



------------------
I love JavaRanch!
Hi everyone,
I realize this topic has been properly addressed, but I find that I have apparently learned this backwards and would appreciate some live human straightening out what I've just got all twisted up.
This post's question boils down to two things:
(1) Is the left operand the reference and the right operand the class?
(2) Which determines which method is invoked, and which determines which variable is accessed?
We know that Khalid says (p. 181): "When a method is invoked on an object using a reference, it is the class of the current object denoted by the reference, not the type of the reference that determines which method implementation will be executed."
So, for example:
superRef = subClassObject;
The class of the current reference: Super
The type of the reference: Sub
Or not?
I learned this backwards and desperately need straightening out.
The following code is adapted from Khalid p. 183, and clearly shows that the left hand operand always determines the method invoked.
Or not. I don't know. I seem to have curled my brain into a ball.
I thank you all for your replies.
-- Caroline
<CODE>
interface IStack {
void push();
void pop();
}
interface ISafeStack extends IStack {
void isEmpty();
void isFull();
}
class StackImpl implements IStack {
public void push() {}
public void pop() {}
public void peek() {}
}

class SafeStackImpl extends StackImpl implements ISafeStack {
public void isEmpty() {}
public void isFull() {}
}
class StackUser {
public static void main(String args[]) {
new StackUser();
}
public StackUser() {
SafeStackImpl safeStackRef = new SafeStackImpl();
separator();
debug("SafeStackImpl safeStackRef.getClass: " + safeStackRef.getClass());
safeStackRef.push();
safeStackRef.pop();
safeStackRef.peek();
safeStackRef.isEmpty();
safeStackRef.isFull();
debug("safeStackRef CAN access push, pop, peek");
debug("safeStackRef CAN access isEmpty, isFull");
separator();
StackImpl stackRef = safeStackRef;
debug("StackImpl stackRef.getClass: " + stackRef.getClass());
stackRef.push();
stackRef.pop();
stackRef.peek();
//stackRef.isEmpty();
//stackRef.isFull();
debug("stackRef CAN access push, pop, peek");
debug("stackRef CANNOT access isEmpty, isFull");
separator();
ISafeStack isafeStackRef = safeStackRef;
debug("ISafeStack isafeStackRef.getClass: " + isafeStackRef.getClass());
isafeStackRef.push();
isafeStackRef.pop();
//isafeStackRef.peek();
isafeStackRef.isEmpty();
isafeStackRef.isFull();
debug("isafeStackRef CAN access push, pop");
debug("isafeStackRef CANNOT acccess peek");
debug("isafeStackRef CAN access isEmpty, isFull");

separator();
IStack istackRef = safeStackRef;
debug("IStack istackRef.getClass: " + istackRef.getClass());
istackRef.push();
istackRef.pop();
//istackRef.peek();
//istackRef.isEmpty();
//istackRef.isFull();
debug("istackRef CAN access IStack push, pop");
debug("istackRef CANNOT access peek");
debug("istackRef CANNOT access isEmpty, isFull");
separator();
Object objRef = safeStackRef;
debug("Object objRef.getclass: " + objRef.getClass());
//objRef.push();
//objRef.pop();
//objRef.peek();
//objRef.isEmpty();
//objRef.isFull();
debug("objRef cannot access anything except Object methods");
StackImpl stackImpl = new StackImpl();// superclass reference
SafeStackImpl safeStackImpl = new SafeStackImpl();// subclass reference
// stackImpl: push, pop, peek
// SafeStackImpl: isFull, isEmpty
// REFERENCE determines method
stackImpl = safeStackImpl;// upcasting
stackImpl.push();
stackImpl.pop();
stackImpl.peek();
//stackIimpl.isEmpty();
//stackImpl.isFull();
// REFERENCE determines method
safeStackImpl = (SafeStackImpl) stackImpl;
safeStackImpl.push();
safeStackImpl.pop();
safeStackImpl.peek();
safeStackImpl.isEmpty();
safeStackImpl.isFull();

}
private void debug(Object arg) { System.out.println(arg.toString()); }
private void separator() { System.out.println("----------------"); }
}
</CODE>



------------------
I love JavaRanch!
It's quite a nice bug! As I said, I send it to Khalid. No way to know for sure I have the right address, though.
I'm going to start a new thread on this topic because I posted incorrect code in the first place. Just to be clear.
More on this later.
Caroline

Originally posted by Maulin, Vasavada:
Hi caroline,
how stupid of me!!! its obvious. it will result into overflow stack exception for following reason,
we r trying to create object of type SubclassB2 in SubclassB2 while writing SuperclassA objrefA = new SubclassB2();
jvm encounters this it tries to create SubclassB2's Object where it encounters the same statement again and again...
it goes on forever...
so...that's how its getting that exception,
oh! man i shd 've recognized it at first sight.
regards,
maulin


To be clear... are all String values known at compile-time "constants"? And are they therefore in the literal pool and ineligible for GC? e.g., any string created at run time is eligible for GC after all references to that String are null?
Thanks.

Originally posted by Peter den Haan:
[B]Yes, Caroline, that's what it means. The second is not just a shorthand for the first. In the first, you assign a reference to the string constant "hello" to string. In the second case, you construct a new String object (which will be allocated on the heap) the contents of which are identical to that of the "hello" string constant.
Taking that knowledge as a starting point, try to predict the output of the following:If you're sceptical, try it...
- Peter[/B]


What would the exam interpret (a) to be? Right (because I'm right) or wrong (because they're going for "You can't make the gc do anything")?

Originally posted by Shyamsundar Gururaj:
Caroline,
I agree with you. In the context of this question choice (a) would also be an answer. But the wording is definitely ambiguous.



------------------
I love JavaRanch!
So, wait, does that mean that:
String string = "hello";
is not gc'd and
String string2 = new String("hello");
is gc'd?
Wouldn't make sense because the first is just shorthand for the second. Am I missing a point?
BTW, the Syngress Java cert book (for which I can post many hundreds of mistakes) makes a point of having the user learn when String objects are gc'd.
But I will take JavaRanch's word for it any day

Caroline

Originally posted by Ragu Sivaraman:
Yeah i did come across these issues and many times i got it wrong
when i choose "string litreal wont be gc'ed" since
the mock exams keys says "the string literal will be gc'ed" becoz they are created using new operator for the first time and optimitized later on...
Thankx for bringing it up and clarifying it
Ragu


<CODE>
a) The garbage collector can be invoked explicitly using a Runtime object.
</CODE>
I would be picky about this wording and I think it's ambiguous. Please tell me what you think of my argument.
Invoking the garbage collector is a discrete action. Whether that gc actually does anything is a separate action.
There is no difference between requesting that the gc do its job and invoking the gc. Once the gc examines the situation, it might or might not do its job. But it must be invoked before it can make that decision. Therefore (a) is true, the garbage collector can be invoked explicitly using System or Runtime.
Once invoked, it may continue or not continue.
Please tell me what you think.
Ms. Literal,
Caroline

[This message has been edited by Caroline Bogart (edited November 23, 2001).]
!!!

[This message has been edited by Caroline Bogart (edited November 22, 2001).]
This is from q. 4.14, p. 111, Khalid.
Given:
<PRE>
// file Base.java
package net.basemaster;
public class Base {
}

javac -d d:\java\packages Base.java

// file UsesBase2.java
import net.basemaster.*;
public class UsesBase2 {
Base b = new Base();//ok
}

javac UsesBase2.java

UsesBase2.java:3: cannot resolve symbol
symbol : constructor Base ()
location: class Base
Base b = new Base(); //ok
^
1 error
</PRE>
Now change UsesBase2 to specify the exact class to be imported:
<PRE>
import net.basemaster.Base;
public class UsesBase2 {
Base b = new Base();//ok
}
</PRE>

I've seen this posted to a newsgroup and the results were the same. Is this a javac bug?
-- Caroline
You are correct. Please re-read the thread for my correction code, in which the SubclassB2 attempts to access public SuperclassA that has protected members.
My apologies.

Originally posted by Manoj Gupta:
The line in your code that you have commented with a [b]//no will work.
objRefA.superclassVarA = 10; //no.
Reference objRefA points to a SubclassB2 object (Superclass references can legally point to a subclass object in Java), which is extending SuperclassA with a public member variable superclassVarA. Public member variables can be accessed with an object.variable notation anywhere.
To see it yourself compile and execute these:
SuperclassA.java

SubclassB2.java:

Compile using
javac -d . *.java
and execute using
java packageB.SubclassB2

[/B]


OK. If I assign a subclass object to a superclass reference, the subclass (object) IS A superclass and the superclass (reference) IS A superclass. So the reference then knows about superclass members but does not know about subclass members.
Cats have paws
Siamese cats have paws and eyes
Cat cat = new SiameseCat();
cat can reference cat.paws
cat cannot referrence cat.eys
OK?
On the other hand:
Siamese scat = new Cat(); // no
All Siamese cats are cats.
Not all cats are Siamese cats.
Compiler error.
How's this so far?

Originally posted by Jane Griscti:
[B]Hi Caroline,
Yes, a subclass can always be assigned to a superclass reference.
A subclass is a specialization of its superclass; it will have all the characteristics of the superclass plus some additional characteristics. For example, in

It will always be true that a SiameseCat is a Cat, it will always have 'paws', so you can always assign a Siamese object to a Cat reference.
However, it will not always be true that a Cat is a SiameseCat.
The declared contract for the SiameseCat class guarantees that all SiameseCat objects will have an attribute 'eyes'. A Cat object does not have that attribute; it would break the SiameseCat contract; so the compiler won't allow you to assign a Cat to a SiameseCat reference.
Hope that helps.
[/B]


You are absolutely correct about the stack overflow.
The example is from Khalid ed. 4 p. 117. I wrote to Khalid to inform him of the unfortunate stack overflow effect of the sample code.
And, I apparently mis-wrote the protected SuperclassA, which should be:
<PRE>
public class SuperclassA {
protected int superclassVarA;
protected void superclassMethodA() {}
}
public class SubclassB2 extends SuperclassA {
SuperclassA objRefA = new SubclassB();
SubclassB objRefB = new SubclassB();
void subclassMethodB() {
objRefB.superclassMethodA();
objRefA.superclassVarA = 10;
}
}
</PRE>


Originally posted by Maulin, Vasavada:
hi,
sorry but i didnt understand ur point. i tried similar code and got stack overflow exception. and where u use protected which u mentioned in first part of ur mail?

can u clear my doubts?
thanks
maulin