Reputation: 2746
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
Reputation: 77930
What if we add a new attribute to Person - we could forget to add it here...
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
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
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
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