Home | Contact Us | FAQ | Search & Site Map | Link to Us
Sign In | Join | Other 45 Sites in Network
HomeAnnouncementsWhite Papers
Discussion GroupsFirst AidDatabasesJavaBeansGUIJava 3DVirtual MachineCORBASecurityToolsGeneral
Java DirectoryOpen Source ProjectsSample Book ChaptersUser GroupsWeb Resources
Related Topics
Databases.NETMore Topics ...

Java Forum / General / August 2007

Tip: Looking for answers? Try searching our database.

Can you copy derived classes of the same superclass?

Thread view: 
BogusException - 26 Aug 2007 05:28 GMT
Wordy version: A single superclass has 2 different derived classes.
Looking for a way to copy one derived class to the other.

Scenario: Superclass S exists. 2 classes are derived from, and extend,
S. The 2 classes are A and B. A and B have unique members that neither
share. They only have their superclass in common. An instance of class
A needs to be copied into a new instance of B.

Of course the unique attributes, methods, etc. of the instance of
class A have no counter in class B, but the attributes that are within
the superclass do. So ideally, all attributes carried by both class A
and B (super included) would be copied, and any non-matching
attributes would not. If there was a [simple] way to do this (meaning
non-class-specific), I would then only have to worry about matching
the outliers.

Any ideas?

TIA!
Eric Jablow - 26 Aug 2007 05:59 GMT
> Of course the unique attributes, methods, etc. of the instance of
> class A have no counter in class B, but the attributes that are within
[quoted text clipped - 3 lines]
> non-class-specific), I would then only have to worry about matching
> the outliers.

If you want a automated way of doing this, consider the
Jakarta Commons Beanutils library.  It has copyProperties
methods that use introspection to determine the common
attributes.

However, I suspect that your class design should be a
little different. Instead of using inheritance, perhaps you
should use composition.

public class A {
   private CommonClass cc;
   private int a1;
   private double a2;
   private Color a3;
   // Accessors, constructors, etc.
}

public class B {
   private CommonClass cc;
   private String b1;
   private long[] b2;
   private Reader b3;
   // Accessors, constructors, etc.
}

Then, you could write statements like a.setCC(b.getCC()),
but if you do, watch out for aliasing.  If CommonClass is
mutable, you really need to use defensive copying.  That's
one of the reasons that Java programmers hate java.util.Date.
Read "Effective Java", by Herb Sutter.

Signature

Respectfully,
Eric Jablow

BogusException - 28 Aug 2007 05:09 GMT
Eric,

Thanks for writing. I found the BeanUtils classes extremely
interesting. Comments inline below:

[...]
> If you want a automated way of doing this, consider the
> Jakarta Commons Beanutils library.  It has copyProperties
> methods that use introspection to determine the common
> attributes.

Worked well-really well, with one exception. When inheriting a class,
that class wasn't copied over. All properties that had matching
counterparts did, which is 1/2 the fight, really. I haven't tried
bringing the super class in with composition yet.

> Then, you could write statements like a.setCC(b.getCC()),

I got out of the docs for copyProperties that it would create a copy
of all attributes. I'll test whether this applies to a class brought
in with composition. It would be best if all was copied.

Will apprise after more testing.

Thanks!

Bogus Exception
BogusException - 29 Aug 2007 01:36 GMT
Eric,

Thanks again for writing. I figured out what I was doing wrong. The
inherited class had to have getters/setters like the derived classes
in order for the copyProperties() to work.

The following is a complete example using copyProperties():

The base class:

package test;

public class CommonClass {
        private String sInherited;
        //
        public String getSInherited() {
            return sInherited;
        }
        public void setSInherited(String inherited) {
            sInherited = inherited;
        }
}

Class A, which is one of 2 classes that extend CommonClass. It has
both unique and common property names:

package test;

public class A extends CommonClass {
   private int iA; // a uniquely named attribute
   private String sName; // a commonly named attribute
   //
    public A(){
   }
   //
    public int getIA() {
        return iA;
    }
    public void setIA(int ia) {
        iA = ia;
    }
    public String getSName() {
        return sName;
    }
    public void setSName(String name) {
        sName = name;
    }
}

Class B:

package test;

public class B extends CommonClass {
   private int iB; // a uniquely named attribute
   private String sName; // a commonly named attribute
   //
   public B(){
   }
   //
    public int getIB() {
        return iB;
    }
    public void setIB(int ib) {
        iB = ib;
    }
   public String getSName() {
        return sName;
    }
    public void setSName(String name) {
        sName = name;
    }
}

Now the test class that will load up A, then copy it to B:

package test;

import org.apache.commons.beanutils.*;

public class TestClass {
    /**
    * @param args
    */
    public static void main(String[] args) {
        System.out.println("Begin...");
        BeanUtilsBean bub = new BeanUtilsBean();
        A a = new A();
        B b = new B();
        //
        a.setIA(1);
        a.setSName("Testing...");
        a.setSInherited("inherited from A");
        //
        try {
            bub.copyProperties(b, a); //(dest, orig)

            System.out.println("-----");
            System.out.println("a.getIA(): " + a.getIA());
            System.out.println("a.getSName(): " + a.getSName());
            System.out.println("a.getSInherited(): " + a.getSInherited());
            System.out.println("b.getIB: " + b.getIB());
            System.out.println("b.getSName(): " + b.getSName());
            System.out.println("b.getSInherited(): " + b.getSInherited());
            System.out.println("-----");
        } catch (Exception ex){
            System.out.println("Exception here: " + ex.toString());
        }
        System.out.println("End...");
    }
}

Output:

Begin...
-----
a.getIA(): 1
a.getSName(): Testing...
a.getSInherited(): inherited from A
b.getIB: 0
b.getSName(): Testing...
b.getSInherited(): inherited from A
-----
End...

Since iB had no counterpart in class A, it was not copied, and assumed
the Java default for ints.

This is exactly the behavior I was hoping for. Thanks for the tip!

Bogus Exception


Free Magazines

Get these publications absolutely FREE for up to 12 months. There are no hidden fees and no obligation. Simply choose a title, complete the application form and submit it. Read more ...

Oracle MagazineNetwork ComputingComputer WorldBio-IT WorldeWeekInformation WeekInfosecurity
 
Sign In
Join
My Latest Posts
My Monitored Threads
My Blog
My Photo Gallery
My Profile
My Homepage

Start New Thread
Enable EMail Alerts
Rate this Thread



©2008 Advenet LLC   Privacy Policy - Terms of Use
This website includes both content owned or controlled by Advenet as well as content owned or controlled by third parties.