Search code examples
javaabstract-classclonesubclasssuperclass

Make a new instance of an unknown subclass using superclass object in java


Here I have an abstract class Person and multiple subclasses:

public abstract class Person {

    public String name;

    public Person(String name) {
        this.name = name;
    }
}

public class ComputerScientist extends Person {

    public String job;

    public ComputerScientist(String name, String job) {
        super(name);
        this.job = job;
    }
}

public class SoftwareEngineer extends Person {

    public String job;

    public SoftwareEngineer(String name, String job) {
        super(name);
        this.job = null;
    }
}

This is what I run:

public static void main(String[] args) {
    List<Person> people = new ArrayList<Person>();
    person.add(new ComputerScientist("ben", "job"));
    person.add(new SoftwareEngineer("larry", "job"));
    Random r = new Random();

    Person person = people.get(r.nextInt(people.size() - 1);
}

Person becomes the same as the Person in the list, how do I get it as a person clone. Cloning and new Instance do not work.

I can probably do it using a copy method (requres me to rewrite a great deal of code) but is there any (perhaps more efficient) way to do it without?


Solution

  • You can create a method to create a new Object of the Person(as per the sub class) and another method to copy the states in the new object. Refer below approach for the basic implementation of the same.

    public abstract class Person{
      ...//your states and methods
      protected void copy(Person copiedPerson){
            copiedPerson.name = this.name;
      }
    
      public abstract Person getCopyPerson();
    }
    
    public class SoftwareEngineer extends Person{
    
         ....//your states and methods
        @override
         protected void copy( Person copiedPerson ){
              super(copiedPerson);
              copiedPerson.job = this.job;
         }
    
        @override
        public Person getCopyPerson(){
           Person copyPerson = new SoftwareEngineer();
           copy(copyPerson);
           return copyPerson;
        }
    
    }
    

    Now whenever you fetch the object of Person, simply call getCopyPerson() on it to get a copy object.