1

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();
}
5
  • 1
    Why not just return new B(whatever);? Commented Mar 6, 2016 at 20:25
  • 1
    Hi @spysmily1. It's hard to visualize the code that you're talking about based on your description. You might have better luck getting a solid answer if you add your code as a minimum, verifiable, reproducible example: stackoverflow.com/help/mcve Commented Mar 6, 2016 at 20:31
  • Please post the actual code that the question is about. Commented Mar 6, 2016 at 20:32
  • I updated with code. Hopefully that helps someone see what I am trying to do. Commented Mar 6, 2016 at 20:48
  • @OliverCharlesworth Well there could be a C, D, E, etc... subclasses. I am looking for the return to be based on the calling subclass. So the return class could be either of those too. Commented Mar 6, 2016 at 20:49

2 Answers 2

0

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();
}
Sign up to request clarification or add additional context in comments.

1 Comment

I never thought of that. I searched everywhere and couldn't find that. It was also hard to find the right search words to use. Thank you for that idea. I haven't searched hook method yet but is it good practice?
0

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();
}

2 Comments

Thanks for the reference link too. I gave the above as an answer cause he was first.
Hey, np! There are two solutions to your issue. I just felt I had to make it complete by providing this other answer. Also, you don't have to justify which answer you give the "accepted" tag: that power is yours and yours alone ;)

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.