aspose file tools*
The moose likes Programmer Certification (SCJP/OCPJP) and the fly likes Sibling assignment Big Moose Saloon
  Search | Java FAQ | Recent Topics | Flagged Topics | Hot Topics | Zero Replies
Register / Login


Win a copy of Soft Skills this week in the Jobs Discussion forum!
JavaRanch » Java Forums » Certification » Programmer Certification (SCJP/OCPJP)
Bookmark "Sibling assignment" Watch "Sibling assignment" New topic
Author

Sibling assignment

Paul Salerno
Ranch Hand

Joined: Jan 17, 2002
Posts: 172

This is from a mock exam.
Answer:
Illegal both at compile and runtime, you cannot assign an object to a sibling reference, even with casting.
I thought I have seen plenty of examples on here regarding GC where this assignment is OK. Can anyone explain why they;re saying this is illegal?
Anonymous
Ranch Hand

Joined: Nov 22, 2008
Posts: 18944
Yes,

"DerivedOne" is a "Parent" plus something
"DerivedTwo" is a "Parent" plus something
"DerivedOne" is not a "DerivedTwo"
"DerivedTwo" is not a "DerivedOne"
for example

When DerivedTwo is created it allocates memory for a and c but no b. If this assigment were legal....
What prints this code?

[ January 29, 2002: Message edited by: Carlos R Ram�rez ]
Paul Salerno
Ranch Hand

Joined: Jan 17, 2002
Posts: 172
What prints this code?
I would say d1 now holds d2 object therefore would print contents of d2. I still think this assignment should be ok, since all we're doing is reassigning the ref var d1.
Junilu Lacar
Bartender

Joined: Feb 26, 2001
Posts: 5287
    
  10

Paul,
The compiler checks for assignment compatibility of the declared types. The VM does a double check at runtime on the actual types.
DerivedOne and DerivedTwo are not assignment compatible because they are siblings. Although they have a common parent, they may extend the parent in very different ways, i.e. they do not have a direct "is a" relationship. You can't say "a DerivedOne is a DerivedTwo or vice versa".
What would be legal at compile time is this code:

The above code would pass compilation. However, at runtime a ClassCastException will be generated at line 3.
Try substituting the following names to make it more meaningful and you'll see the logic in having Java behave this way:
Parent --> Mammal
DerivedOne --> Whale
DerivedTwo --> Mouse


Junilu - [How to Ask Questions] [How to Answer Questions]
Valentin Crettaz
Gold Digger
Sheriff

Joined: Aug 26, 2001
Posts: 7610
The assignment would be ok if the compile-time type of d1 and d2 was Parent, like this:

You have to understand that DerivedOne and DerivedTwo have NOTHING in common regardless of the fact that htey both inherit from Parent... They are sibling, just sibling...
Moreover, think of Parent as Fruit and DerivedOne as Apple and DerivedTwo as Orange. Now you must admit that an Apple and an Orange have nothing in common. They can both be referenced by a reference of type Fruit but an object of type Apple cannot be referenced by a reference of type Orange and vice-versa...
HIH


SCJP 5, SCJD, SCBCD, SCWCD, SCDJWS, IBM XML
[Blog] [Blogroll] [My Reviews] My Linked In
Corey McGlone
Ranch Hand

Joined: Dec 20, 2001
Posts: 3271
When dealing with inheritance, I've found that it is most important to remember one simple rule:
You can use a child anywhere a parent is expected.
Note, this says you can use a child anywhere a parent is expected. It doesn't say that you can use a sibling or cousin or whatever. When you have an inheritance relationship, you have an "is a" relationship. Take the following example:

I hope this makes sense to you. Here's another way to explain it.
A child class is a specialization of a parent class. Let's assume we have the class Animal. An animal class might have a few basic traits, like a name, number of feet, a backbone, etc. Here's a simple Animal class:

Now, let's think about a couple things that might extend Animal, such as bird and dog. What might those classes look like. Obviously, they'll have everything that an Animal would have, but they'll each have a little bit more. Here are some class definitions for Bird and Dog:

As you can see, a bird "is a" type of animal as a dog "is a" type of animal. Therefore, the following code snippet is legal:

Since a variable of type Animal can reference anything that "is an" animal, we can assign an Animal object, a Bird object, or a Dog object to it. Now, what happens if we try to assign a Dog object to a Bird variable:

Since b is a Bird variable, we should be able to call it's layEggs method. Yet, we've tried to assign a Dog object to b. Can a dog lay eggs? Not one that I've ever seen! Since a dog "is not" a bird, we can't assign a dog to a bird variable (and vice versa).
Also, what about assigning parents to siblings. Look at this code:

Once again, since d is a Dog reference, we should be able to tell anything that is assigned to it to catch a frisbee. But, can any animal catch a frisbee? Can a frog? or a tadpole? An animal "is not" a dog, rather a dog "is a" animal. Therefore, you can't assign a parent to a child variable, either.
I know this reply has gotten horribly long, but this is an essential topic and you'll have to understand this very well if you want to go far with Java. Please let me know if you're still having problems.
Corey


SCJP Tipline, etc.
Paul Salerno
Ranch Hand

Joined: Jan 17, 2002
Posts: 172
Thanks guys for the great explanations. I was just under the impression that d1 was just a reference variable then after reassignment ie d1 = d2 the d1 would just loose its reference to the original object, where it could then be GC'd.
Heres an example I had previously although both reference vars point to the same object.

I realize this wont compile but when a=b the object to which "a" was originally reffering to is now GC'd. This is what Chubb gave me, great example ha?
Valentin Crettaz
Gold Digger
Sheriff

Joined: Aug 26, 2001
Posts: 7610
Excellent explanation Corey
You explained with Animals, I explained with Fruits, let's hope it clear things up
Paul Salerno
Ranch Hand

Joined: Jan 17, 2002
Posts: 172
But I think I got it now, after viewing the three posts combined. Thanks guys
Praveena khandavalli
Greenhorn

Joined: Jan 05, 2002
Posts: 21
hi corey,
nice explanation..very clear with the concept now.. thanx
Praveena
Paul Salerno
Ranch Hand

Joined: Jan 17, 2002
Posts: 172
One more thing:

The compiler checks for assignment compatibility of the declared types. The VM does a double check at runtime on the actual types.
DerivedOne and DerivedTwo are not assignment compatible because they are siblings. Although they have a common parent, they may extend the parent in very different ways, i.e. they do not have a direct "is a" relationship. You can't say "a DerivedOne is a DerivedTwo or vice versa".

I realize this is an illegal assignment, Im just looking for a quick answer because Im seeing something different in a multiple choice mock.
They say that it will compile, but throw a ClassCastException at Runtime, but I'm under the impression that it wont even compile based upon the above "quoted" information.
Paul Salerno
Ranch Hand

Joined: Jan 17, 2002
Posts: 172
to clear up he says
Parent p = new Parent();
DerivedOne d1 = new DerivedOne();
DerivedTwo d2 = new DerivedTwo();
d2 = d1;

Legal at compile time, but may fail at runtime.
but this one:
Parent p = new Parent();
DerivedOne d1 = new DerivedOne();
DerivedTwo d2 = new DerivedTwo();
d1 = (DerivedOne)d2;

Illegal both at compile and runtime.
Paul Salerno
Ranch Hand

Joined: Jan 17, 2002
Posts: 172
Hey guys,
So I guess I'm wondering if those two assessments are correct. Again I realize that sibling to sibling assignment is invalid, but I'm still trying to determine exactly what types of errors occur in the two cases above?
Thanks!
Junilu Lacar
Bartender

Joined: Feb 26, 2001
Posts: 5287
    
  10

Originally posted by Paul Salerno:
to clear up he says
Parent p = new Parent();
DerivedOne d1 = new DerivedOne();
DerivedTwo d2 = new DerivedTwo();
d2 = d1;

Legal at compile time, but may fail at runtime.
but this one:
Parent p = new Parent();
DerivedOne d1 = new DerivedOne();
DerivedTwo d2 = new DerivedTwo();
d1 = (DerivedOne)d2;

Illegal both at compile and runtime.


No, Paul. Neither of these is legal at compile time because you can't say that a DerivedOne 'is a' DerivedTwo or vice versa.
As we've tried to explain previously,
An Orange 'is a' Fruit (vice versa may be true)
An Apple 'is a' Fruit (vice versa may be true)
A Whale 'is a' Mammal (vice versa may be true)
A Mouse 'is a' Mammal (vice versa may be true)
BUT
An Apple is NOT an Orange (not ever, nor vice versa)
A Whale is NOT a Mouse (not ever, nor vice versa)
By the same token,
A DerivedOne is NOT a DerivedTwo (not ever, nor vice versa)
You can't trick the compiler into thinking otherwise because it is aware of the class hierarchy.
You can, however, say:
1: Parent p = new DerivedOne();
2: DerivedTwo d2 = (DerivedTwo) p;
Because in line 1, the statement "Parent IS A DerivedOne, or vice versa" applies.
Line 2 is legal because in effect, you are telling the compiler "This reference p, which you only know to be a Parent references an object that is really a DerivedTwo."
The compiler, God bless its trusting soul , takes your word for it and goes about its business. As long as one class IS A descendant of the other (doesn't matter which one, hence, the "or vice versa"), the compiler will be happy.
The Runtime is not as gullible. It goes back and double checks your assurance. If it finds out you weren't being truthful, it will tell you in no uncertain terms that you have made an Invalid Class Cast. Line 2 will placate the compiler, but not the Runtime (because it knows... <"twilight zone" music> ).
[ January 31, 2002: Message edited by: Junilu Lacar ]
Junilu Lacar
Bartender

Joined: Feb 26, 2001
Posts: 5287
    
  10

Originally posted by Paul Salerno:
I realize this is an illegal assignment, Im just looking for a quick answer because Im seeing something different in a multiple choice mock.

Oops, sorry for that long-winded explaination just now. I was under the impression that you hadn't gotten it.
The short of it is:
Compiler checks that this is true:
- Declared type (DT) of Right Hand Side (RHS) instanceof DT of Left Hand Side (LHS) (or if reverse is true, require a valid cast as an assurance)
Runtime checks that this is true:
- Actual type of RHS instanceof DT of LHS (violations to this will be dealt with a ClassCastException )
As somebody explained before, it is important that you are clear on the difference between Declared Type and Actual Type. In
Parent p = new DerivedOne();
the Actual Type is DerivedOne while the Declared Type is Parent.
[ January 31, 2002: Message edited by: Junilu Lacar ]
Paul Salerno
Ranch Hand

Joined: Jan 17, 2002
Posts: 172
Thanks for your quick reply, this is really helping me nail down my study notes!

thirdly I'm assuming that since the compiler checks the declared types that the following will compile and run:
Paul Salerno
Ranch Hand

Joined: Jan 17, 2002
Posts: 172
Im sorry, just forget this thread I have it figured out. Thanks
 
I agree. Here's the link: http://aspose.com/file-tools
 
subject: Sibling assignment