0

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?

TheChubbyPanda
  • 1,721
  • 2
  • 16
  • 37
  • 2
    Create an `abstract clone()` method which your subclasses have to implement. Then you can call `person.clone()` – QBrute Mar 21 '18 at 12:20

3 Answers3

1

I'm not a fan of clone() - see also Clone() vs Copy constructor- which is recommended in java

So, instead use a copy constructor or copy method, that accepts a person and then transfers the relevant information

Emerson Cod
  • 1,990
  • 3
  • 21
  • 39
  • Good answer. Also the (`Object`'s) `clone` method really is misleading as it only does a shallow copy. Which for example leaves `String` fields 'uncloned' which is more often than not unexpected and leads to errors. – Ben Mar 21 '18 at 12:27
1

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.

nits.kk
  • 5,204
  • 4
  • 33
  • 55
0

Make your class cloneable with implements with Cloneable interface. and at object user .clone() method to clone of person class object

Birbal Singh
  • 1,062
  • 7
  • 16
  • 3
    While you are (I assume) trying to get the correct idea through you should try rewording your answer as it's currently really not understandable. – Ben Mar 21 '18 at 12:25