Prev: eclipselink @table annotation
Next: Java Type System
From: Michael Preminger on 17 Mar 2010 15:04 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
From: Eric Sosman on 17 Mar 2010 16:31 On 3/17/2010 3:04 PM, Michael Preminger wrote: > 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. -- Eric Sosman esosman(a)ieee-dot-org.invalid
From: Mike Schilling on 17 Mar 2010 17:33 Eric Sosman wrote: > On 3/17/2010 3:04 PM, Michael Preminger wrote: >> 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. 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 ...
From: Eric Sosman on 18 Mar 2010 10:20 On 3/17/2010 5:33 PM, Mike Schilling wrote: > Eric Sosman wrote: >> On 3/17/2010 3:04 PM, Michael Preminger wrote: >>> 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. > > 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." -- Eric Sosman esosman(a)ieee-dot-org.invalid
From: Mike Schilling on 18 Mar 2010 11:45
Eric Sosman wrote: > On 3/17/2010 5:33 PM, Mike Schilling wrote: >> Eric Sosman wrote: >>> On 3/17/2010 3:04 PM, Michael Preminger wrote: >>>> 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. >> >> 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? 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 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." That last is going a bit too far; there are many jurisdictions in which euthanasia is still illegal. |