• Post Reply Bookmark Topic Watch Topic
  • New Topic
programming forums Java Mobile Certification Databases Caching Books Engineering Micro Controllers OS Languages Paradigms IDEs Build Tools Frameworks Application Servers Open Source This Site Careers Other Pie Elite all forums
this forum made possible by our volunteer staff, including ...
Marshals:
  • Campbell Ritchie
  • Tim Cooke
  • paul wheaton
  • Liutauras Vilda
  • Ron McLeod
Sheriffs:
  • Jeanne Boyarsky
  • Devaka Cooray
  • Paul Clapham
Saloon Keepers:
  • Scott Selikoff
  • Tim Holloway
  • Piet Souris
  • Mikalai Zaikin
  • Frits Walraven
Bartenders:
  • Stephan van Hulst
  • Carey Brown

IS-A questions

 
Ranch Hand
Posts: 38
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Hi Ranchers.

I'm quite confused about the IS-A concept, in regards with upcasting and downcasting. Here is the question:
Assume:
class A {}
class B extends A {}
...
(main)

A a = new A();

A b = new B();

if I do:
b = a;
in order to know if this statement compiles or not, should I check for the reference type (in this case A = A passes the IS-A test) or check for the object type - in which case would be like B() = A() does not pass the IS-A test ?

I usually test the IS-A from right to left. So if I have
A a = new B();
I would ask myself, is B an A ? - which, in this case, is true. Is this a correct way to check for the IS-A test ?

And also, when I have a cast, say
B b1 = (B)a;

How should I check it in order to recognize that it compiles, but fails at runtime ?

To summarize, my doubts are:
Should I check the reference type on the left side, with the object type on the right side ? Or should both the reference type be checked ? Or perhaps should I check the object typeonly in presence of a cast ?

As you see, I need some clarification

Thanks in advance,
Sergio.
 
Ranch Hand
Posts: 1032
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Hi Sergio,

This is all you need to know (I'm ignoring null and interfaces in this discussion for simplification.)

Referencing rule: A reference is an identifier with a specific associated type. A reference of type X can point to objects of class X, or to objects of any of X's subtypes.

A reference can be bound to an object via:
1. Assignment of a newly created object, as in:
A a = new B();

2. Assignment of an existing reference variable, as in:
A b = a;

When you bind an object to a reference, you need to make sure that the reference can point to that object according to the referencing rule I wrote above. That's all there is to it.

Here's some special cases:
Upcasting: When you attempt to assign to a reference of type X a reference that is either of type X or any of X's subtypes (technically, upcasting would require the type to be a subtype of X and not X itself, but I'm simplifying.) Upcasting always works, no problems at either compile time or run time. No explicit casting is required.
Examples:

Downcasting: When you attempt to assign to a reference of type X a reference that is of a supertype of X. Notice that downcasting must always include an explicit cast. Also, if the class you are casting is not a supertype of, a subtype of, or the same type of the reference type that you are assigning to, this will result in a compiler error. Furthermore, if the object pointed to by the reference you are assigning from is not assignment compatible with the reference type you are assigning to according to the referencing rule, a ClassCastException will be issued at run time.
Examples:


I hope that helps. Let me know if there is anything that is not clear enough.
 
Ranch Hand
Posts: 45
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Hi Sergio
whenever I see these IS-A questions I divide it into two parts compile time and runtime.

1.Compile Time
At compile time we should remember compiler does not have any information about real object.Thing it cares about is references.

Now if we write


if we call a method using reference variable a then compiler will look for it in class A only because compiler simply sees reference variable a as type of Class A it has no knowledge about real object B.

2.Runtime
Now at runtime real object is created means JVM knows that B is real object.If any method is called useing reference variable a then JVM will first check the class B. If method is not found here then JVM will look for it in class A.

For casting check here

I hope this helps you.



 
Ranch Hand
Posts: 140
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
IS-A test always checks if the object in the right side is assignable to the reference type in the left side or not.
To test the assignable part, you need to first check if both the types fall in same inheritance tree or not and if they fall,
check if the type in right side appears down in the inheritance tree than type in the left side.

Hope the above explanation helps.

 
Sergio Marcello
Ranch Hand
Posts: 38
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Many thanks, now I think I'm getting more

I understand that:

- check from right to left is correct;

- when I assign one reference to another, I have to check only the reference type to assert if compiles or not:

(class B extends class A)

A a = new A();
B b = new B();

b = a; //will not compile, since A is not a B.
a = b; //will compile, since B is a A.

- Whereas if I have a cast, I have to check the cast type with the reference first, to assert that it compiles:
B b1 = (B)a; // the (B) on the richt is-a B of the left side, so it compiles, but at runtime, the object type must be checked:
a on the right side, points to an A object, which is not a B on the left side.

Am I on the right path ?

Sergio.
 
Rajshekhar Paul
Ranch Hand
Posts: 140
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

- Whereas if I have a cast, I have to check the cast type with the reference first, to assert that it compiles:


You need to take care of the thing that the reference/object type in the left side and reference/object type in the right side, fall into the same
inheritance tree. If they don't, code will not compile!

B b1 = (B)a; // the (B) on the richt is-a B of the left side, so it compiles, but at runtime, the object type must be checked:


Yoy need to check the object types during coding time only, unless it's gonna produce a runtime exception!
 
Ranch Hand
Posts: 826
Eclipse IDE Oracle Chrome
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Ruben Soto wrote:

When you bind an object to a reference, you need to make sure that the reference can point to that object according to the referencing rule I wrote above. That's all there is to it.

 
Ranch Hand
Posts: 32
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Hi Sergio, as Ruben and others explained it very well, I am just re-phrasing it again. Essentially you just need to do '3 checks' in order to find out whether a given code will compile/ not-compile or fail at runtime.

Referencing rule: A reference is an identifier with a specific associated type. A reference of type X can point to objects of class X, or to objects of any of X's subtypes.



Check 1 : when assign "reference of type B" (e.g B b) to a "reference that is supertype of B" (e.g a). -> it is Downcasting - must include explicit cast.


Check 2 : if the class you are casting is not a supertype of, a subtype of, or the same type of the reference type that you are assigning to, this will result in a compiler error.



Check 3 : if the object pointed to by the reference on right hand side(e.g a) is not assignment compatible with the reference type you are assigning to (e.g b) according to the referencing rule, a ClassCastException will be issued at run time. Which means code at 'check 1' will compile fine but fail at run time.


Thanks
 
Sergio Marcello
Ranch Hand
Posts: 38
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Thanks all, that makes sense for me now.

Hopefully I'll remember that on the real exam...

Sergio.
 
My cellmate was this tiny ad:
Smokeless wood heat with a rocket mass heater
https://woodheat.net
reply
    Bookmark Topic Watch Topic
  • New Topic