Adam
Adam

Reputation: 2746

Automate Construction of a Subclass when passed an Instance of a Superclass

I am creating an instance of a subclass by passing in an instance of the superclass. This is my code - which works - but which doesn't feel right.

My question is: Doesn't Java have native support for this using Object casting or suchlike?

Or am I forced to use reflection/BeanUtils if I really wanted to automate this?

The example below has been simplified to highlight the problem. My real world code has many many more fields.

Thanks, Adam.

import java.util.Date;


public class Person
{
    private String name;
    private Date dateOfBirth;


    public String getName()
    {
        return name;
    }


    public void setName(String name)
    {
        this.name = name;
    }


    public Date getDateOfBirth()
    {
        return dateOfBirth;
    }


    public void setDateOfBirth(Date dateOfBirth)
    {
        this.dateOfBirth = dateOfBirth;
    }
}


public class Soldier extends Person
{
    private String rank;


    public Soldier(final Person p)
    {
        /*
         * Isn't there a better way of doing this? What if we add a new
         * attribute to Person - we could forget to add it here...
         */
        setName(p.getName());
        setDateOfBirth(p.getDateOfBirth());
    }


    public String getRank()
    {
        return rank;
    }


    public void setRank(String rank)
    {
        this.rank = rank;
    }
}

Upvotes: 1

Views: 96

Answers (4)

Maxim Shoustin
Maxim Shoustin

Reputation: 77930

What if we add a new attribute to Person - we could forget to add it here...

  • Or interface that should take care about these methods.
  • Or write methods in super class

So from followed example we pass interface of Person to `Solder:

PersonItf

public interface PersonItf {
    String getName();
    String getDateOfBirth();    
}

Solder

public class Soldier extends Person {
    private String rank;


    public Soldier(final PersonItf p)
    {
        // now we call all inteface methods
        setName(p.getName());
        setDateOfBirth(p.getDateOfBirth());
    }


    public String getRank()
    {
        return rank;
    }


    public void setRank(String rank)
    {
        this.rank = rank;
    }
}

Person

public abstract class Person implements PersonItf
{
    private String name;
    private String dateOfBirth;


    @Override
    public String getName(){
        return name;
    }


    public void setName(String name){
        this.name = name;
    }

    @Override
    public String getDateOfBirth(){
        return dateOfBirth;
    }


    public void setDateOfBirth(String dateOfBirth){
        this.dateOfBirth = dateOfBirth;
    }
}

main

public static void main(String[] args) {

    PersonItf person = new Person();

    Soldier solder = new Soldier(person);      

}

Upvotes: 1

arcy
arcy

Reputation: 13153

You could have a static method in Person that takes two person instances, and sets all the field values of one values of the other.

public class Person
{
  public static setFieldValues(Person targetPerson, Person sourcePerson)
  {
    // set field values here
  }
}

then call it with

public class Soldier
{
  public Solder(Person p)
  {
    setFieldValues(this, p);
  }
}

at least this way the field values will be within the Person class, not all revealed to the subclass.

Upvotes: 0

Michiel Rop
Michiel Rop

Reputation: 99

You don't need to pass a person object

public class Soldier extends Person{
private String rank;

public String getRank()
{
    return rank;
}


public void setRank(String rank)
{
    this.rank = rank;
}

}

Now you can just make a Soldier object:

Soldier soldier = new Soldier();
soldier.setRank("sergant");
soldier.setName("John");

Have a look at the concepts of OO in java

Upvotes: 0

Michiel Rop
Michiel Rop

Reputation: 99

Another way is use the wrapper or adapter pattern:

public class Soldier extends Person{
private String rank;
private Person person;


public Soldier(final Person p)
{
    this.person = p;
}


public String getRank()
{
    return rank;
}


public void setRank(String rank)
{
    this.rank = rank;
}

public String getName()
{
    return person.getName();
}


public void setName(String name)
{
    person.setName(name);
}


public Date getDateOfBirth()
{
    return person.getDateOfBirth();
}


public void setDateOfBirth(Date dateOfBirth)
{
    person.setDateOfBirth(dateOfBirth);
}

}

Upvotes: 0

Related Questions