Constructing an object from a superclass object

Discussion in 'Java' started by Michael Preminger, Mar 17, 2010.

  1. 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
    Michael Preminger, Mar 17, 2010
    #1
    1. Advertising

  2. Michael Preminger

    Eric Sosman Guest

    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
    lid
    Eric Sosman, Mar 17, 2010
    #2
    1. Advertising

  3. 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 ...
    Mike Schilling, Mar 17, 2010
    #3
  4. Michael Preminger

    Eric Sosman Guest

    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
    lid
    Eric Sosman, Mar 18, 2010
    #4
  5. 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.
    Mike Schilling, Mar 18, 2010
    #5
  6. Michael Preminger

    Roedy Green Guest

    On Wed, 17 Mar 2010 12:04:59 -0700 (PDT), Michael Preminger
    <> wrote, quoted or indirectly quoted someone
    who said :

    >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.
    Roedy Green, Mar 18, 2010
    #6
    1. Advertising

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

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Mike Wahler
    Replies:
    3
    Views:
    416
    Gavin Deane
    Aug 1, 2003
  2. Replies:
    1
    Views:
    330
    Simon
    Jul 24, 2006
  3. Marco Wedekind
    Replies:
    11
    Views:
    5,810
    Marco Wedekind
    Apr 26, 2006
  4. Evan Klitzke
    Replies:
    0
    Views:
    362
    Evan Klitzke
    Aug 2, 2007
  5. bart van deenen
    Replies:
    6
    Views:
    752
    bart van deenen
    Mar 3, 2009
Loading...

Share This Page