Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is there a way to instantiate a child class with parent object in java?

I have a base class say

class A {
   private String name;
   private String age;

   //setters and getters for same
}

and a child class say

class B extends A {
 private String phone;
 private String address;

  //setters and getters for same
}

now I've an instance of A and besides this I have to set the fields in B as well, so code would be like,

A instanceOfA = gotAFromSomewhere();
B instanceOfB = constructBFrom(instanceOfA);
instanceOfB.setPhone(getPhoneFromSomewhere());
instanceOfB.setAddress(getAddressFromSomewhere());

can I instantiate B with given A, but I don't want to do this way,

B constructBFrom(A instanceOfA) {
  final B instanceOfB = new B();
  instanceOfB.setName(instanceOfA.getName());
  instanceOfB.setPhone(instanceOfA.getAge());

  return B;
}

rather what I'd love to have some utility with function which is generic enough to construct object as in,

public class SomeUtility {

   public static <T1, T2> T2 constructFrom(T1 instanceOfT1, Class<T2> className) {

      T2 instatnceOfT2 = null;

      try {
         instatnceOfT2 = className.newInstance();
         /*
         * Identifies the fields in instanceOfT1 which has same name in T2
         * and sets only these fields and leaves the other fields as it is.
         */
      } catch (InstantiationException | IllegalAccessException e) {
         // handle exception
      }          

      return instatnceOfT2;
   }
}

so that I can use it as,

B constructBFrom(A instanceOfA) {
   return SomeUtility.constructFrom(instanceOfA, B.class);
}

Moreover, use case will not be only limited to parent-child classes, rather this utility function can be used for adapter use cases.

PS- A and B are third party classes I've to use these classes only so I can't do any modifications in A and B.

like image 729
shelly Avatar asked Jul 07 '14 17:07

shelly


2 Answers

The good practice is to have a factory class which "produces" the instances of B.

public class BFactory {
    public B createBFromA(A a) { ... }
}

You have to write the code of the factory method as there is no standard way of creating a child class based on its parent class. It's always specific and depends on the logic of your classes.

However, consider if it is really what you need. There are not many smart use cases for instantiating a class based on the instance of its parent. One good example is ArrayList(Collection c) - constructs a specific list ("child") containing the elements of the generic collection ("base").

Actually, for many situation there is a pattern to avoid such strange constructs. I am aware it's probably not applicable to your specific case as you wrote that your Base and Child are 3rd party classes. However your question title was generic enough so I think you may find the following useful.

  1. Create an interface IBase
  2. Let the class Base implement the interface
  3. Use composition instead of inheritance - let Child use Base instead of inheriting it
  4. Let Child implement IBase and delegate all the methods from IBase to the instance of Base

Your code will look like this:

public interface IBase {
    String getName();
    int getAge();
}

public class Base implements IBase {
    private String name;
    private int age;
    // getters implementing IBase
}

public class Child implements IBase {
    // composition:
    final private IBase base;        
    public Child(IBase base) {
        this.base = base;
    }
    // delegation:
    public String getName() {
        return base.getName();
    }
    public int getAge() {
        return base.getAge();
    }
}

After you edited your question, I doubt even stronger that what you want is good. Your question looks more like an attempt of a hack, of violating (or not understanding) the principles of class-based object oriented concept. Sounds to me like someone coming from the JavaScript word and trying to keep the JavaScript programming style and just use a different syntax of Java, instead of adopting a different language philosophy.

Fun-fact: Instantiating a child object with parent object is possible in prototype-based languages, see the example in JavaScript 1.8.5:

var base = {one: 1, two: 2};
var child = Object.create(base);
child.three = 3;

child.one;   // 1
child.two;   // 2
child.three; // 3
like image 197
Honza Zidek Avatar answered Nov 02 '22 14:11

Honza Zidek


In my opinion the way you want to avoid is very appropriate. There must be a piece of such code somewhere.

If you can't put that method in the target class just put it somewhere else (some factory). You should additionaly make your method static.

Take a look at Factory method pattern.

2nd option would be extending B and place this method as factory static method in that new class. But this solution seems to be more complicated for me. Then you could call NewB.fromA(A). You should be able then use your NewB instead of B then.

like image 32
damienix Avatar answered Nov 02 '22 14:11

damienix