Reputation: 57
I have an abstract superclass that has concrete methods used by my subclasses. In at least one of my methods, I would like to return a new object of the same type.
For a better example I have a class A with a field (int num). I have class B which extends A and I create a class B object named classB. classB.someMethod should square num and return a new class B object with this squared value. I don't want to alter the original instance.
I've read about reflection a bit because that's what came up a lot during my searches. newInstance() was suggested frequently. I've also read that reflection can be bad. Is there a better way to go about with what I am trying to do? It's for a personal class I'm creating for openGL programming and could do it many ways but always try to practice keeping things as simple as possible. I could elaborate on my class if needed.
public class A(){
private int num;
public A(int num){
this.num = num;
}
public A square(A a){
temp = a.num * a.num;
return new class same type as the sublcass(temp);
}
}
public class B extends A(){
public B(int num){
super(num);
}
}
public static void main(String...args){
B first = new B(4);
B second = B.square();
}
Upvotes: 1
Views: 1428
Reputation: 21576
Use a hook method (abstract method in superclass), to generate instances of the subclasses.
If you want to have the specific return type in the superclass, then you need a type variable, holding the most specific class reference. Just keep in mind, that this makes your code more difficult to understand.
Like this:
public class A<SUB extends A<SUB>> {
private int num;
public A(int num){
this.num = num;
}
public SUB square(){
int temp = num * num;
return newInstance(temp);
}
protected abstract SUB newInstance(int temp);
}
public class B extends A<B> {
public B(int num){
super(num);
}
protected B newInstance(int temp) {
retunr new B(temp);
}
}
public static void main(String...args){
B first = new B(4);
B second = first.square();
}
Upvotes: 1
Reputation: 35427
You can override methods as long as the type is assignable to the parent one. You can see its definition here and apply it to your code using the following pattern.
public class A {
private int num;
public A(int num){
this.num = num;
}
public A square(A a) {
temp = a.num * a.num;
return newInstance(temp);
}
protected A newInstance(int num) {
return new A(num);
}
}
public class B extends A(){
public B(int num){
super(num);
}
public B square() {
return (B)super.square();
}
protected B newInstance(int num) { // Yes, this is allowed
return new B(num);
}
}
public static void main(String...args){
B first = new B(4);
B second = B.square();
}
Upvotes: 1