Reputation: 2377
I'm building a base/parent class in Java that's going to have several methods for creating the class itself and I'm wondering if there's any way to have the parent class return instances of the child class instead of returning instances of the parent class that then have to be cast to the child?
For example, here's my parent class:
public abstract class SFObject
{
// Variables
protected String mID;
protected String mName;
// Function called to create ourselves from a DiffObject
public abstract SFObject CreateFromDiffObject(DiffObject object);
// Function called to create a list of ourselves from a query
public List<SFObject> CreateListFromQuery(Connection connection, String query)
{
// Run the query and loop through the results
ArrayList<SFObject> objects = new ArrayList<SFObject>();
for (DiffObject object : connection.Query(query))
objects.add(CreateFromDiffObject(object));
return objects;
}
}
If I create a child class based on my SFObject class, the two functions in my child class will still return an SFObject (that needs to be cast to my child class type) or a list of SFObjects (that need to be individually cast to my child class type). Is there any way (maybe using Reflections) to have my child class returns instances of itself as itself and not as SFObjects?
Upvotes: 3
Views: 6197
Reputation: 86774
What you are describing is known as a covariant return type.
Class A {
A getInstance() { ... }
}
Class B extends A {
@Override
B getInstance() { ... }
}
This has been allowed since Java 1.5.
Upvotes: 1
Reputation: 23903
Exactly for this functionalities are proposed the factory methods, as you already implemented. In the child class you can change the return type without offending the method declaration. A sample for your case would be something like:
public abstract class SFObject {
// Variables
protected String mID;
protected String mName;
// Function called to create ourselves from a DiffObject
public abstract SFObject CreateFromDiffObject(DiffObject object);
// Function called to create a list of ourselves from a query
public List<? extends SFObject> CreateListFromQuery(Connection connection, String query) {
// Run the query and loop through the results
ArrayList<SFObject> objects = new ArrayList<SFObject>();
for (DiffObject object : connection.Query(query))
objects.add(CreateFromDiffObject(object));
return objects;
}
}
class SFObjectChild extends SFObject {
@Override
public SFObjectChild CreateFromDiffObject(DiffObject object) {
SFObjectChild result = new SFObjectChild();
//...
return result;
}
@Override
public List<? extends SFObjectChild> CreateListFromQuery(Connection connection,
String query) {
return null;//..;
}
}
This is acceptable because the return type of the children class is still a kind of (hierarchical speaking) the parent.
Be aware of java code conventions (methods in camel case starting with low, e.g. createFromDiffObject
).
Upvotes: 0
Reputation: 22084
Not sure if I really understand your Problem correct because it sounds to me lke this:
class p
{
public static p createParent()
{
return new p();
}
public static c createChild()
{
return new c();
}
}
Of course it doesn't have to be static, just thought of some kind of factory.
Upvotes: 0
Reputation: 185
If you place the child class object inside of the parent object, methods called will run from the child class. But it will look like the parent object on the surface
public class A{
method 1(){//do some stuff}
method 2(){//do some stuff}
}
public class B extends A{
method 1(){super.method 1()
//do some other stuff}
method 2(){super.method 2()
//do some other stuff}
}
public class test{
A a = new B();
//any method called on 'a' will come from the child class
// But 'a' is the parent object
}
Upvotes: 0