I have two classes where one class inherits the other one as given below:
public class UserData {
protected final String emailAddress;
protected final String name;
public UserData(final String emailAddress, final String name) {
this.emailAddress = emailAddress;
this.name = name;
}
public Optional<String> getEmailAddress() {
return Optional.ofNullable(this.emailAddress);
}
public Optional<String> getName() {
return Optional.ofNullable(this.name);
}
}
public class EmployeeData extends UserData {
protected final String designation;
public EmployeeData(
final String emailAddress,
final String name,
final String designation
) {
super(emailAddress, name);
this.designation = designation;
}
public Optional<String> getDesignation() {
return Optional.ofNullable(this.designation);
}
}
I need to create method in another class that can return either one of these objects and have all getters accessible. I already tried making the return type UserData
for both kinds of objects (example given below) but that way, I cannot access the getDesignation
getter for EmployeeData. Is there a better way inheritance can be setup to avoid this problem where I cannot access child-specific properties?
public UserData getData() {
if (...some condition) {
return new EmployeeData("[email protected]", "myName", "Dev")
}
else {
return new UserData("[email protected]", "myName");
}
}
I did look into these stackoverflow questions but couldn't quite figure it out for my use case
- C# how to make a function that can return either child or parent class
- What's the equivalent of C# IEnumerable in Java? The covariant-capable one, not the Iterable
CodePudding user response:
Because the object we are returning is of type UserData
, we will be unable to call methods that are added within the child class, EmployeeData
. You could create the getDesignation()
method inside the UserData
class and have it return an empty optional object.
public Optional<String> getDesignation() {
return Optional.empty();
}
In this case, you can now override the method within the EmployeeData
class to return designation
as an Optional
like this,
@Override
public Optional<String> getDesignation() {
return Optional.ofNullable(this.designation);
}
Now you will have access to the getDestination()
method from returned object of getData()
, but you will have to be careful and understand that if the returned type is of UserData
, then when calling getDesignation()
you will be receiving an Optional.empty()
object.