3
votes

Assuming I have a super class that has 3 parameters in it's constructor and i am inheriting this class that also has a constructor with 3 parameters, and I want to call the super class constructor but before I want to do some logic on the sub class first, I can call a static method that receives those 3 parameters but I have to return only one, so this is the solution I came up with

public class someClass extends  SuperClass {
    public someClass(int a,int b,int c) {
         super(func(a,b,c),b,c);
    }
    public static int func(int a,int b,int c){
        //usage a b c
        return a;
    }
}

It seems a bit ugly and I was wondering if there is a better solution to use the parameters myself and then call super regularly. Note that i cannot change the Super class or that usages of the sub classes and therefore factory Design Pattern

3
... you're aware that a constructor shouldn't really contain 'logic', right? so, if I understand this correctly: you want to run business logic on an object that isn't even completely instantiated? - Stultuske
Does your func method always return a (which means the super call would always be super(a,b,c)? If that's the case, I see no reason of calling func before super(a,b,c). - Eran
I want to call to external logic like opening a file, which is not fully related to the object itself i'm instantiated - Nitzan Farhi
I'm not entirely sure if I understand correctly what you're trying to do, but what about the Builder pattern? you could perform your logic before calling the constructor that way. - Stultuske
@Turing85 Absolutely not! Please take a look at their help center. This is example code, highly illegal at Code Review. - Mast

3 Answers

9
votes

To get the logic out of your constructor, you can easily create a factory method in your subclass:

public class SomeClass extends SuperClass {
    private SomeClass(int a, int b, int c) {
        super(a, b ,c);
    }

    public static SomeClass create(int a, int b, int c){
        // calculate a for constructor

        return new SomeClass(a, b, c);
    }
}

Then you can create instances as follows:

SomeClass someClass = SomeClass.create(1, 2, 3);
5
votes

In Java you are not allowed to execute another statement before the call to super. The trick you mentioned works, but you cannot refactor your code to have the call to func in a statement before the call to super.

In my experience, issues like this often hint at some design issue. Maybe you can solve the underlying problem by re-thinking about the responsibilities of the two involved classes.

1
votes

You could also use the builder pattern

public class SomeClass extends SuperClass {
    public static class Builder {
        private int a, b, c;
        public Builder withA(int a) { 
            this.a = a;
            return this;
        }
        public Builder withB(int b) { ... }
        public Builder withC(int c) { ... }
        public SomeClass build() {
            // logic goes here
            return new SomeClass(...)
        }
    }

    // hide this from public use, use Builder instead
    protected SomeClass(int a, int b, int, c) {
        super(a, b, c);
    }
}

SomeClass someClass = new SomeClass.Builder().
    withA(1).
    withB(2).
    withC(3).
    build();