Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > Java > Another question about inheritance (up-casting and down-casting)

Reply
Thread Tools

Another question about inheritance (up-casting and down-casting)

 
 
kevin
Guest
Posts: n/a
 
      01-07-2005
Hi all:

Sorry to bother you again

Still the question about inheritance,please see this codes below
first:

// codes start
class base{//a base class

// constructor
public base(){
System.out.println("base class construct");
}
// perform
public void perform(){
System.out.println("base class perform");
}
// destructor
public void finalize(){
System.out.println("base class destruct");
}
}


class subbase extends base{// derive from base

// constructor
public subbase(){
System.out.println("sub class construct");
}
// perform
public void perform(){
System.out.println("sub class perform");
}
// destructor
public void finalize(){
System.out.println("sub class destruct");
}
}

public class casting{// test casting class
// constructor
public casting(){
System.out.println("begin casting test");
}

public static void main(String args[]){
base father = new base();
subbase son = new subbase();

father.perform();
son.perform();

father = (base)son; // <1>
father.perform();

son = (subbase)father; // <2>
son.perform();

father = (base)((subbase)father); // <3>
father.perform();
}
}

// codes end

************************************************** *
and the execution result is:
// begin
base class construct
base class construct
sub class construct
base class perform
sub class perform
sub class perform // <a>
sub class perform // <b>
sub class perform // <c>
// end

************************************************** **

My question is: there are 3 castings in the codes(e.g. <1><2><3>),but
why they perform not as I like, I cast the subclass son to base class
at <1>, but at <a>,father.perform() don't print "base class perform",
the situation is similar in <2><a> and <3><c>,so, why?


************************************************** **
And I am confused about how "casting" behave?
for example:

base class: sub class derive from base
+---------------+ +------------------------------+
| int nbase | | int nbase int nsub |
----------------- --------------------------------
| void fbase() | | void fbase() void fsub() |
+---------------+ +------------------------------+

so, if I declare:

base a = new base(); // a should contains nbase and fbase()
sub b = new sub(); // b should contains nbase,nsub and
fbase(),fsub()
base c;
sub d;

c = (base)b; // ? what c contains ? like a or like b
// that is to say if son class upcasting to father
class
// if the member belongs to son class should be
truncated?
d = (sub)c; // ? what d contains ? like a or like b
// that is to say if d get the members belongs to son
class
// automatically
// d == b ? i mean if equal in memory profile

************************************************** *****

I am a little confused about how memory allocation changes when
upcasting
or downcasting ?



that's all

thank you!


kevin
 
Reply With Quote
 
 
 
 
Harish
Guest
Posts: n/a
 
      01-07-2005
in short: the function overriding in java is always virtual.

so even if you type cast a derived class object to a base class object
and then invoke a function,(which is overridden in the derived class)
it'll end up calling the derived class implementation.

hmmm.. am i doing someonelese'shomework?


"kevin" <(E-Mail Removed)> wrote in message
news:(E-Mail Removed) om...
> Hi all:
>
> Sorry to bother you again
>
> Still the question about inheritance,please see this codes below
> first:
>
> // codes start
> class base{//a base class
>
> // constructor
> public base(){
> System.out.println("base class construct");
> }
> // perform
> public void perform(){
> System.out.println("base class perform");
> }
> // destructor
> public void finalize(){
> System.out.println("base class destruct");
> }
> }
>
>
> class subbase extends base{// derive from base
>
> // constructor
> public subbase(){
> System.out.println("sub class construct");
> }
> // perform
> public void perform(){
> System.out.println("sub class perform");
> }
> // destructor
> public void finalize(){
> System.out.println("sub class destruct");
> }
> }
>
> public class casting{// test casting class
> // constructor
> public casting(){
> System.out.println("begin casting test");
> }
>
> public static void main(String args[]){
> base father = new base();
> subbase son = new subbase();
>
> father.perform();
> son.perform();
>
> father = (base)son; // <1>
> father.perform();
>
> son = (subbase)father; // <2>
> son.perform();
>
> father = (base)((subbase)father); // <3>
> father.perform();
> }
> }
>
> // codes end
>
> ************************************************** *
> and the execution result is:
> // begin
> base class construct
> base class construct
> sub class construct
> base class perform
> sub class perform
> sub class perform // <a>
> sub class perform // <b>
> sub class perform // <c>
> // end
>
> ************************************************** **
>
> My question is: there are 3 castings in the codes(e.g. <1><2><3>),but
> why they perform not as I like, I cast the subclass son to base class
> at <1>, but at <a>,father.perform() don't print "base class perform",
> the situation is similar in <2><a> and <3><c>,so, why?
>
>
> ************************************************** **
> And I am confused about how "casting" behave?
> for example:
>
> base class: sub class derive from base
> +---------------+ +------------------------------+
> | int nbase | | int nbase int nsub |
> ----------------- --------------------------------
> | void fbase() | | void fbase() void fsub() |
> +---------------+ +------------------------------+
>
> so, if I declare:
>
> base a = new base(); // a should contains nbase and fbase()
> sub b = new sub(); // b should contains nbase,nsub and
> fbase(),fsub()
> base c;
> sub d;
>
> c = (base)b; // ? what c contains ? like a or like b
> // that is to say if son class upcasting to father
> class
> // if the member belongs to son class should be
> truncated?
> d = (sub)c; // ? what d contains ? like a or like b
> // that is to say if d get the members belongs to son
> class
> // automatically
> // d == b ? i mean if equal in memory profile
>
> ************************************************** *****
>
> I am a little confused about how memory allocation changes when
> upcasting
> or downcasting ?
>
>
>
> that's all
>
> thank you!
>
>
> kevin



 
Reply With Quote
 
 
 
 
Virgil Green
Guest
Posts: n/a
 
      01-07-2005
kevin wrote:
> Hi all:
>
> Sorry to bother you again
>
> Still the question about inheritance,please see this codes below
> first:
>
> // codes start
> class base{//a base class
>
> // constructor
> public base(){
> System.out.println("base class construct");
> }
> // perform
> public void perform(){
> System.out.println("base class perform");
> }
> // destructor
> public void finalize(){
> System.out.println("base class destruct");
> }
> }
>
>
> class subbase extends base{// derive from base
>
> // constructor
> public subbase(){
> System.out.println("sub class construct");
> }
> // perform
> public void perform(){
> System.out.println("sub class perform");
> }
> // destructor
> public void finalize(){
> System.out.println("sub class destruct");
> }
> }
>
> public class casting{// test casting class
> // constructor
> public casting(){
> System.out.println("begin casting test");
> }
>
> public static void main(String args[]){
> base father = new base();
> subbase son = new subbase();
>
> father.perform();
> son.perform();
>
> father = (base)son; // <1>
> father.perform();
>
> son = (subbase)father; // <2>
> son.perform();
>
> father = (base)((subbase)father); // <3>
> father.perform();
> }
> }
>
> // codes end
>
> ************************************************** *
> and the execution result is:
> // begin
> base class construct
> base class construct
> sub class construct
> base class perform
> sub class perform
> sub class perform // <a>
> sub class perform // <b>
> sub class perform // <c>
> // end
>
> ************************************************** **
>
> My question is: there are 3 castings in the codes(e.g. <1><2><3>),but
> why they perform not as I like, I cast the subclass son to base class
> at <1>, but at <a>,father.perform() don't print "base class perform",
> the situation is similar in <2><a> and <3><c>,so, why?


Casting doesn't change the nature of the object being referenced. It only
changes the way you reference it. Any overridden method will continue to be
overridden, even if you access it through a reference whose type is a parent
of the actual object.

> ************************************************** **
> And I am confused about how "casting" behave?
> for example:
>
> base class: sub class derive from base
> +---------------+ +------------------------------+
>> int nbase | | int nbase int nsub |

> ----------------- --------------------------------
>> void fbase() | | void fbase() void fsub() |

> +---------------+ +------------------------------+
>
> so, if I declare:
>
> base a = new base(); // a should contains nbase and fbase()
> sub b = new sub(); // b should contains nbase,nsub and
> fbase(),fsub()
> base c;
> sub d;
>
> c = (base)b; // ? what c contains ? like a or like b
> // that is to say if son class upcasting to father
> class


c contains a reference to the object that was created when you did "new
sub()". The nature of the object didn't change in any way because you upcast
it to a variable whose object type is a parent of the actual object.

> // if the member belongs to son class should be
> truncated?
> d = (sub)c; // ? what d contains ? like a or like b
> // that is to say if d get the members belongs to son
> class
> // automatically
> // d == b ? i mean if equal in memory profile


Nothing is removed from an object just because you upcast a reference to it.
You are just limited (perhaps, assuming new methods are defined in the
subclass) in how you can work with the object via the new reference. You
could, for example, downcast it again and still have all the access you
originally had via the 'sub' type reference.

> ************************************************** *****
>
> I am a little confused about how memory allocation changes when
> upcasting
> or downcasting ?


It doesn't. Objects are objects. References are references. Non-primitive
variables are references to objects. Assigning to a different, compatible
variable doesn't change the object in any way.

--
Virgil


 
Reply With Quote
 
Andrew McDonagh
Guest
Posts: n/a
 
      01-07-2005
kevin wrote:
> Hi all:
>
> Sorry to bother you again


Not a problem, its what this NG is for.

>
> Still the question about inheritance,please see this codes below
> first:
>
> // codes start
> class base{//a base class
>
> // constructor
> public base(){
> System.out.println("base class construct");
> }
> // perform
> public void perform(){
> System.out.println("base class perform");
> }
> // destructor
> public void finalize(){
> System.out.println("base class destruct");
> }
> }
>
>
> class subbase extends base{// derive from base
>
> // constructor
> public subbase(){
> System.out.println("sub class construct");
> }
> // perform
> public void perform(){
> System.out.println("sub class perform");
> }
> // destructor
> public void finalize(){
> System.out.println("sub class destruct");
> }
> }


minor point Java does not have destructors - finalizers are not the
same. When the Garbage collector kicks in to free memory it may call an
objects finalizer(), but there's no guarantee that it will under certain
conditions.

>
> public class casting{// test casting class
> // constructor
> public casting(){
> System.out.println("begin casting test");
> }
>
> public static void main(String args[]){
> base father = new base();
> subbase son = new subbase();
>
> father.perform();
> son.perform();
>
> father = (base)son; // <1>
> father.perform();
>


all that has occurred here is that you have over made the 'father'
reference point to the son object. You can do this, because the 'son'
object is a kindOf 'base' class. Its worth noting that the explicit cast
you have done here, is not actually needed and could be removed without
effecting the outcome.

When you call father.perform(); you are still calling the 'subbase'
class method of the object that 'father' now points too.

this is because in Java all methods are virtual by default. Therefore it
does not matter that the method exists on the base class and the subbase
class, its the subbase.perform() method that will be called.

This is what polymorphic means.

Also note, that unless subbase.perform() explicitly calls:
super.perform(); then whatever the base.perform() method does, will not
happen.

i.e.

// perform
public void perform(){
super.perform();
System.out.println("sub class perform");
}


Note, that now both the 'son' and 'father' references point to the
subbase object.

The object that 'father' use to point too, is now no longer available to
the code and so may at sometime be garbage collected.


> son = (subbase)father; // <2>
> son.perform();


Now that the 'son' and 'father' references point to the subbase object,
the code above is really doing the same as the previous perform(), just
via a different Type of reference.

>
> father = (base)((subbase)father); // <3>
> father.perform();
> }
> }
>
> // codes end
>
> ************************************************** *
> and the execution result is:
> // begin
> base class construct
> base class construct
> sub class construct
> base class perform
> sub class perform
> sub class perform // <a>
> sub class perform // <b>
> sub class perform // <c>
> // end
>
> ************************************************** **
>
> My question is: there are 3 castings in the codes(e.g. <1><2><3>),but
> why they perform not as I like, I cast the subclass son to base class
> at <1>, but at <a>,father.perform() don't print "base class perform",
> the situation is similar in <2><a> and <3><c>,so, why?
>


The beauty of polymorphic behavior is that it does not matter what type
of reference you have to an object, when you call its polymorphic
method, the most derived class method will be called first.

This allows you to derive a new class from a base, ond optionally
override the base class behavior if you want too or not.

If you do, then your overridden method will be called rather than the
base class one.

>
> ************************************************** **
> And I am confused about how "casting" behave?
> for example:
>
> base class: sub class derive from base
> +---------------+ +------------------------------+
> | int nbase | | int nbase int nsub |
> ----------------- --------------------------------
> | void fbase() | | void fbase() void fsub() |
> +---------------+ +------------------------------+
>
> so, if I declare:
>
> base a = new base(); // a should contains nbase and fbase()
> sub b = new sub(); // b should contains nbase,nsub and
> fbase(),fsub()
> base c;
> sub d;
>
> c = (base)b; // ? what c contains ? like a or like b
> // that is to say if son class upcasting to father


As above, the up cast is unnecessary. as all that is happening is that
the base class typed reference 'c' is now pointing to an object which is
a kindOf 'base'. Whether it is a base, or any derived class of base is
irrelevant.

It does mean however that from the 'c' reference you can only treat the
'b' object as if it was a base class.

> class
> // if the member belongs to son class should be
> truncated?
> d = (sub)c; // ? what d contains ? like a or like b
> // that is to say if d get the members belongs to son
> class
> // automatically
> // d == b ? i mean if equal in memory profile
>
> ************************************************** *****
>
> I am a little confused about how memory allocation changes when
> upcasting
> or downcasting ?


There are no real memory changes when casting. What happens is that the
references that pointed to one object, now point to another, thats all.

>
>
>
> that's all
>
> thank you!
>


no problem.
 
Reply With Quote
 
Jeff
Guest
Posts: n/a
 
      01-07-2005
Part of your problem in understanding what's going to happen is,
I think, the way you have re-used and re-assigned the variables
in your main() method.

See comments in code below...

kevin wrote:
> Hi all:
>
> Sorry to bother you again
>
> Still the question about inheritance,please see this codes below
> first:
>
> // codes start
> class base{//a base class
>
> // constructor
> public base(){
> System.out.println("base class construct");
> }
> // perform
> public void perform(){
> System.out.println("base class perform");
> }
> // destructor
> public void finalize(){
> System.out.println("base class destruct");
> }
> }
>
>
> class subbase extends base{// derive from base
>
> // constructor
> public subbase(){
> System.out.println("sub class construct");
> }
> // perform
> public void perform(){
> System.out.println("sub class perform");
> }
> // destructor
> public void finalize(){
> System.out.println("sub class destruct");
> }
> }
>
> public class casting{// test casting class
> // constructor
> public casting(){
> System.out.println("begin casting test");
> }
>
> public static void main(String args[]){
> base father = new base();
> subbase son = new subbase();
>
> father.perform();
> son.perform();


So far, so good. Everything as expected, right?

>
> father = (base)son; // <1>
> father.perform();


Now father refers to a subbase (specifically, the same object
that was originally assigned to the variable son earlier)

>
> son = (subbase)father; // <2>
> son.perform();


Here's where you get into trouble. In <1> above, father is
already referring to the original value of son, so this action
actually DOES NOT CHANGE what son refers to. son still refers to
a subbase object.

>
> father = (base)((subbase)father); // <3>
> father.perform();


Again, father still refers to the original subbase (son) object
from the assignment in <1>


I hope this helps. Try another sample program, but don't re-use
your variables. Create new ones for each behavior you are trying
to demonstrate.

--
Jeff
jlar310 at yahoo
 
Reply With Quote
 
Eric Sosman
Guest
Posts: n/a
 
      01-07-2005
kevin wrote:
> Hi all:
>
> Sorry to bother you again


For future reference, comp.lang.java.help is a newsgroup
more suited to "elementary" questions like this.

> Still the question about inheritance,please see this codes below
> first:
> [... code snipped; see up-thread ...]
>
> My question is: there are 3 castings in the codes(e.g. <1><2><3>),but
> why they perform not as I like, I cast the subclass son to base class
> at <1>, but at <a>,father.perform() don't print "base class perform",
> the situation is similar in <2><a> and <3><c>,so, why?


Here's a discipline that may help you understand what's
going on: Remember always that the variables like `father'
and `son' are not objects, but references to objects. You
do not call a method of `father' or of `son', but a method
of the object `father' or `son' refers to. Using a cast to
change the type of the reference value does not affect the
nature of the target object: no matter which reference you
use for the method call, the object itself provides the
method's implementation.

If you think about it a bit, you'll realize that this
is the "right" way for things to work. Suppose you have a
collection called `zoo' full of various Animal objects.
Actually, none of them is an Animal; they're all subclasses
of Animal: Gorilla extends Animal, Titmouse extends Animal,
TasmanianDevil extends Animal, and so on. Every Animal
implements an eat() method, so the code for feeding time
at the zoo looks like

for (Iterator it = zoo.iterator(); it.hasNext(); ) {
Animal inmate = (Animal)it.next();
inmate.eat();
}

Now, if the first Animal is an Octopus, the first inmate.eat()
call should invoke Octopus' eat() method. And if the second
is a Cobra, the second inmate.eat() call should invoke Cobra's
eat() method, and so on. I put it to you that this is the way
you want method invocation to work: if the Animal-ness of the
`inmate' reference controlled which method implementation is
called, how would you feed the Anaconda and the Armadillo?

> And I am confused about how "casting" behave?
> for example:
>
> base class: sub class derive from base
> +---------------+ +------------------------------+
> | int nbase | | int nbase int nsub |
> ----------------- --------------------------------
> | void fbase() | | void fbase() void fsub() |
> +---------------+ +------------------------------+
>
> so, if I declare:
>
> base a = new base(); // a should contains nbase and fbase()


`a' refers to an object of the class `base'. This object
has an `nbase' field and implements an `fbase' method.

> sub b = new sub(); // b should contains nbase,nsub and
> fbase(),fsub()


`b' refers to an object of the class `sub'. This object
has `nbase' and `nsub' fields, and implements `fbase' and
`fsub' methods. (It's not clear from your diagram whether
the `sub' object inherits `nbase' and `fbase', or whether
it overrides them -- using "overrides" loosely with `nbase').

> base c;
> sub d;
>
> c = (base)b; // ? what c contains ? like a or like b
> // that is to say if son class upcasting to father
> class


`c' refers to the same `sub' object that `b' does. The
only difference is that the compiler will not allow you to
write `c.nsub' or `c.fsub()', because `c' is also capable of
referring to a `base' object that lacks these members. Note
that the `sub' object itself is unchanged. (By the way, the
cast is unnecessary: every `sub' is a `base', so you can use
a `sub' reference anywhere you can use a `base' reference.
Every Hummingbird is an Animal, so Animal x = new Hummingbird()
is perfectly all right and requires no cast.)

> // if the member belongs to son class should be
> truncated?
> d = (sub)c; // ? what d contains ? like a or like b
> // that is to say if d get the members belongs to son
> class
> // automatically


`d' refers to the same `sub' object that `b' and `c' do.
The cast is required here, because `c' is capable of referring
to a plain `base' object that is not a `sub'. Every Hummingbird
is an Animal, but not all Animals are Hummingbirds.

> // d == b ? i mean if equal in memory profile


`d == b' is true: Both reference variables refer to the
same object.

> I am a little confused about how memory allocation changes when
> upcasting
> or downcasting ?


It does not change at all: The target object is not affected
by (is not even aware of) the type of the variable that refers
to it.

--
http://www.velocityreviews.com/forums/(E-Mail Removed)

 
Reply With Quote
 
Ryan Stewart
Guest
Posts: n/a
 
      01-08-2005
"kevin" <(E-Mail Removed)> wrote in message
news:(E-Mail Removed) om...
> Hi all:
>
> Sorry to bother you again
>
> Still the question about inheritance,please see this codes below
> first:
>

[...]
I'm sure you got plenty of good advice from everyone here. I'm afraid I didn't
take the time to read everything. I am just going to interject that based on
your questions, you appear to trying to learn Java by trial and error. Try
working through some basic Java tutorials or a good book. People here tend to be
very patient with beginners who are truly trying to learn, but that patience is
not without limit. Try this for starters:
http://java.sun.com/docs/books/tutorial/

Here is the index to Sun's tutorials:
http://java.sun.com/docs/books/tutor...ybigindex.html

And this should clear up your inheritance questions if the eloquent responses
you've recieved have not already done so:
http://java.sun.com/docs/books/tutor...aOO/index.html

In addition, a simple Google search for "java tutorial" will bring up tons of
good (and not so good, of course) sites.


 
Reply With Quote
 
Ryan Stewart
Guest
Posts: n/a
 
      01-08-2005
"Andrew McDonagh" <(E-Mail Removed)2s.com> wrote in message
news:crmkqc$7i7$(E-Mail Removed)2surf.net...
> minor point Java does not have destructors - finalizers are not the same. When
> the Garbage collector kicks in to free memory it may call an objects
> finalizer(), but there's no guarantee that it will under certain conditions.
>

To clarify, an object's finalizer will be called before the object's storage is
reused, but that may never be necessary.

> There are no real memory changes when casting. What happens is that the
> references that pointed to one object, now point to another, thats all.
>

No. Casting causes the reference type to be different. It still points at the
same object.


 
Reply With Quote
 
Andrew McDonagh
Guest
Posts: n/a
 
      01-08-2005
Ryan Stewart wrote:
> "Andrew McDonagh" <(E-Mail Removed)2s.com> wrote in message
> news:crmkqc$7i7$(E-Mail Removed)2surf.net...
>
>>minor point Java does not have destructors - finalizers are not the same. When
>>the Garbage collector kicks in to free memory it may call an objects
>>finalizer(), but there's no guarantee that it will under certain conditions.
>>

>
> To clarify, an object's finalizer will be called before the object's storage is
> reused, but that may never be necessary.
>
>
>>There are no real memory changes when casting. What happens is that the
>>references that pointed to one object, now point to another, thats all.
>>

>
> No. Casting causes the reference type to be different. It still points at the
> same object.
>
>


I think we are both saying the same thing, but from different angles.

in the case of

Integer i = new Integer(1);

// We could have done ...

Object o = (Object)i;

//which is a legal but unnecessary upcast.

// Then followed by...

Integer anotherI = (Integer)o;

And so I agree, with completely with your statement.

However, in the OPs code we had the following situation

Integer i1 = new Integer(1);
Integer i2 = new Integer(2);

Object o1 = (Object)i1;

o1 = (Object)i2;

So, in this situation, the o1 reference is now pointing to a different
object.
 
Reply With Quote
 
kevin
Guest
Posts: n/a
 
      01-08-2005
Now I know what I want to know.

Thank you all!!

 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
inheritance, multiple inheritance and the weaklist and instance dictionaries Rouslan Korneychuk Python 8 02-10-2011 04:02 AM
Interface inheritance vs Implementation inheritance. Daniel Pitts Java 27 02-27-2008 01:37 AM
Private Inheritance and Publice Inheritance karthikbalaguru C++ 9 09-10-2007 01:05 PM
mul. inheritance & overloading operator new/delete solved by virtual base inheritance? cppsks C++ 0 10-27-2004 07:49 PM
Private access modifier and Inheritance (Inheritance implementation in Java) maxw_cc Java 1 12-21-2003 11:38 AM



Advertisments