Can you copy derived classes of the same superclass?

B

BogusException

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!
 
E

Eric Jablow

BogusException said:
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.

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.
 
B

BogusException

Eric,

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

On Aug 26, 12:59 am, (e-mail address removed) (Eric Jablow) wrote:
[...]
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
 
B

BogusException

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
 

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,981
Messages
2,570,188
Members
46,731
Latest member
MarcyGipso

Latest Threads

Top