Не по порядку цепочечные конструкторы - PullRequest
3 голосов
/ 22 ноября 2011
public class ParentClass
{
    public ParentClass(int param);
}

public class MyClass extends ParentClass
{
    private int _a;
    private int _b;
    private int _c;

    public MyClass(String input)
    {
        _a=CalculateA(input);
        _b=CalculateB(_a);
        _c=CalculateC(_a);
        super(_b+_c);
    }

    //a expensive procedure
    private int CalculateA(String text);

    private int CalculateB(int a);
    private int CalculateC(int a);  
}

Java не позволяет цепочечным конструкторам быть чем-то отличным от первого метода, помещенного в конструктор. Цепные конструкторы не могут вызывать нестатические методы в качестве аргументов (что исключает возможность использования Initialsers, возвращающих значение, которое они инициализируют).

Как мне получить вышеуказанный код, используя легальную Java?

Ответы [ 2 ]

3 голосов
/ 22 ноября 2011

Редактировать Действительно, Java не позволяет конструктору выполнять какие-либо вычисления перед вызовом конструктора класса родителя, даже если они включают только статические методы (как и ваши calculateX) и результаты присваивается только переменным, которые являются частными для класса (например, ваши _a, _b и _c) или локальными для конструктора.

Однако есть способ обойти это: вызвать другой конструктор с результатом вызова calculateX, назначенного его параметру - тогда вы можете получить доступ к этому результату через другой конструктор.

public class MyClass extends ParentClass {
    private int _a,_b,_c;

    public MyClass(String input) {
        this(calculateA(input));
    }

    private MyClass(int a) {
        this(a, calculateB(a), calculateC(a));
    }

    private MyClass(int a, int b, int c) {
        super(b + c);
        this._a = a;
        this._b = b;
        this._c = c;
    }

    private static int calculateA(String text) {
        try {Thread.sleep(1000);} catch (Exception e) {}  // expensive ;-)
        return text.length();
    }

    private static int calculateB(int a) { /* ... */ }
    private static int calculateC(int a) { /* ... */ }
}

Редактировать 2 При большем количестве вычислений или промежуточных результатов, сохраняемых для последующего использования, этот подход приведет к еще более длинной цепочке конструкторов, состоящей только из this(...) -коллсов. Более причудливое решение с использованием только двух конструкторов, публичного и частного, возможно с помощью вспомогательного класса (разумно внутреннего класса):

    public MyClass(String input) {
        this(new InitCalcResult(input));
    }

    private MyClass(InitCalcResult initCalcResult) {
        super(initCalcResult.initB + initCalcResult.initC);
        this._a = initCalcResult.initA;
        this._b = initCalcResult.initB;
        this._c = initCalcResult.initC;
    }

    private static class InitCalcResult {
        private int initA, initB, initC;

        InitCalcResult(String input) {
            initA = calculateA(input);
            initB = calculateB(initA);
            initC = calculateC(initA);  
        }
    }

(используя те же закрытые поля и статические методы calculateX, что и выше).

1 голос
/ 22 ноября 2011

Вы можете сделать что-то вроде этого.

public abstract class ParentClass
{
    public ParentClass(String input){
        int a = getData(input);
        /* Do what ever u need to do with a*/
    };

    public abstract int getData(String input);
}


public class MyClass extends ParentClass
{
    private int _a;
    private int _b;
    private int _c;

    public MyClass(String input)
    {
        super(input);
    }

    public int getData(String input){
         _a=CalculateA(input);
         _b=CalculateB(_a);
         _c=CalculateC(_a);
         return _b+_c;
    }

    //a expensive procedure
    private int CalculateA(String text){/* return int */};

    private int CalculateB(int a){/* return int */};
    private int CalculateC(int a){/* return int */};  
}

Поскольку getData является абстрактным, вызывается функция базового класса.А суперкласс получит необходимые данные.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...