Constructing an object from a superclass object

M

Michael Preminger

Hello!

I have an application where I use different types of persons.
Sometimes I need to convert a general Person (superclass) into a
specific one(subclass)

Is there a way to do it per constructor of the subclass, like:

public Subperson (Person person)
without explicitly copying the member values from the super object
and destroying it later?

Or do I need to do it outside the class, like

Subperson sp = (Subperson) person ?

I would prefer the former, if it was possible.

Thanks

Michael
 
E

Eric Sosman

Hello!

I have an application where I use different types of persons.
Sometimes I need to convert a general Person (superclass) into a
specific one(subclass)

Is there a way to do it per constructor of the subclass, like:

public Subperson (Person person)
without explicitly copying the member values from the super object
and destroying it later?

Or do I need to do it outside the class, like

Subperson sp = (Subperson) person ?

I would prefer the former, if it was possible.

Since the Subperson has attributes that an ordinary Person
lacks, there's no way to transform a plain Person into a
Subperson.

You can, as in your constructor example, build a brand-new
Subperson and copy (or derive) some of its data from a separate
Person object. But the Person object does not "become" a
Subperson thereby; the two objects have independent existences.

On the other hand, if you start with a Subperson and want
to view it/him/her as a plain Person, that's easy: a Subperson
already *is* a Person, and has all a Person's attributes. And
if you have a Person reference that happens to point to an
actual Subperson instance (viewing it only as a Person), you
can "down-cast" to a Subperson again:

Person p = new Subperson("John Galt");
// do Person-like things with p
// can't get at Subperson-like things via p

This works because a Subperson *is* a Person.

Subperson s = (Subperson)p;
// now s and p refer to the same object, but
// s can access its Subpersonhood in addition
// to its Personhood

This works because the Subperson is still a Subperson, even
though you viewed it as merely a plain Person for a while.

Person p2 = new Person("Archibald Leach");
// do Person-like things with p2
Subperson s2 = (Subperson)p2; // ClassCastException!

This fails because a plain Person is *not* a Subperson.
 
M

Mike Schilling

Eric said:
Since the Subperson has attributes that an ordinary Person
lacks, there's no way to transform a plain Person into a
Subperson.

You can, as in your constructor example, build a brand-new
Subperson and copy (or derive) some of its data from a separate
Person object. But the Person object does not "become" a
Subperson thereby; the two objects have independent existences.

On the other hand, if you start with a Subperson and want
to view it/him/her as a plain Person, that's easy: a Subperson
already *is* a Person, and has all a Person's attributes. And
if you have a Person reference that happens to point to an
actual Subperson instance (viewing it only as a Person), you
can "down-cast" to a Subperson again:

Person p = new Subperson("John Galt");
// do Person-like things with p
// can't get at Subperson-like things via p

This works because a Subperson *is* a Person.

Subperson s = (Subperson)p;
// now s and p refer to the same object, but
// s can access its Subpersonhood in addition
// to its Personhood

This works because the Subperson is still a Subperson, even
though you viewed it as merely a plain Person for a while.

Person p2 = new Person("Archibald Leach");
// do Person-like things with p2
Subperson s2 = (Subperson)p2; // ClassCastException!

This fails because a plain Person is *not* a Subperson.

If Subperson is Serializeable, you could

1. Serialize it to a ByteArrayOutputStream
2. Paying careful attention to the serialization spec, make the changes to
the resulting bytes that make it look like a serialized Subperson instead of
a serialized Person.
3. Deserailize it.

Not that I recommend this, mind you ...
 
E

Eric Sosman

If Subperson is Serializeable, you could

1. Serialize it to a ByteArrayOutputStream
2. Paying careful attention to the serialization spec, make the changes to
the resulting bytes that make it look like a serialized Subperson instead of
a serialized Person.
3. Deserailize it.

I guess you mean "if Person is Serializable?" That is,
you're going to serialize a Person instance, twiddle the bytes,
and deserialize to a Subperson?

Yeah, well, but that's just a roundabout (and filthy) way of
doing the copy that the O.P. wanted to avoid.
Not that I recommend this, mind you ...

"Not recommend" isn't strong enough language. You should
be using words like "abominate" and "revile" and "no jury in
the world would convict the perpetrator's killer."
 
M

Mike Schilling

Eric said:
I guess you mean "if Person is Serializable?" That is,
you're going to serialize a Person instance, twiddle the bytes,
and deserialize to a Subperson?

Yes, you're right.
Yeah, well, but that's just a roundabout (and filthy) way of
doing the copy that the O.P. wanted to avoid.

Well, it avoids having to hard-code the names of the fields to be copied,
and I think I could write a generalized version of it that would allow
copying any object into a subclass, provided the object is serializeable and
its serialization hasn't been too customized.
"Not recommend" isn't strong enough language. You should
be using words like "abominate" and "revile" and "no jury in
the world would convict the perpetrator's killer."

That last is going a bit too far; there are many jurisdictions in which
euthanasia is still illegal.
 
R

Roedy Green

I have an application where I use different types of persons.
Sometimes I need to convert a general Person (superclass) into a
specific one(subclass)

Is there a way to do it per constructor of the subclass, like:

public Subperson (Person person)
without explicitly copying the member values from the super object
and destroying it later?

I have been complaining about this for a long time. A copy
constructor like that could be implemented so efficiently as a single
move bytes instruction. As it is, you have to write it out field by
field. The problem is maintenance. Every time you add a field, you
have to maintain your copy constructor.

It is a bug generator. There are so many tiny slips you could make.

What you could do is write a generator that looks at the base class
code and generates the code for a copy constructor. You run this any
time you modify the base class. This avoids buggy code, but still
takes longer than it need do.

The last time I brought it up, Sun said there was not enough interest
in it to implement an efficient syntax.
--
Roedy Green Canadian Mind Products
http://mindprod.com

Responsible Development is the style of development I aspire to now. It can be summarized by answering the question, “How would I develop if it were my money?” I’m amazed how many theoretical arguments evaporate when faced with this question.
~ Kent Beck (born: 1961 age: 49) , evangelist for extreme programming.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,756
Messages
2,569,535
Members
45,008
Latest member
obedient dusk

Latest Threads

Top