2016-01-16 9 views
1

Я использую составные классы для группировки функциональных возможностей.
Но класс A (с композитом A1) получил наследование B (с композитом B1), и поведение, существующее в A1, будет адаптировано к B1, но окончательный a1 должен быть экземпляром B1, чтобы это работало ,составное наследование: как назначить конечное поле в конструкторе подкласса, которое зависит от значения «this» (обратная ссылка)?

Обяснение: У меня есть ways, чтобы убедиться, что составной экземпляр происходит правильно (только его составным партнером).

Невозможно присвоить объект B1 для a1 конечного поля:

class finalFieldTestFails{ 
    class A1{ 
     A1(A a){} 
    } 

    class A{ 
     protected final A1 a1; 
     A(){ 
     this.a1 = new A1(this); 
     } 

     A(A1 a1){ 
     this.a1 = a1; 
     } 
    } 

    class B1 extends A1{ 
     B1(B b){ 
     super(b); 
     } 
    } 

    class B extends A{ 
     //B(){ super.a1=new B1(this); } //FAIL: cant change final value 
     //B(){super(new B1(this));} //FAIL: cant use 'this' or 'super' 
    } 
} 

PS .: ответ не должен включать в себя трюки безопасности отражения, если это возможно.

+1

Это может помочь, если вы можете объяснить, что именно вы пытаетесь сделать, может быть, с примером, который проще следовать? В противном случае он выглядит как ваш пример, поскольку он подтверждает ожидаемое поведение в Java Language Spec ... поэтому, если это не отвечает на ваш вопрос, возможно, вам нужно изменить свой вопрос? –

+0

@KevinHooke thats проблема, я не мог найти более простой способ написать это, то есть минимальный, может быть, если я отформатирую его лучше? я также объяснил, как мне нужно работать. Я почти уверен, что есть способ преодолеть это, не используя рефлексию с вызовами безопасности. –

+1

Возможно, лучший вопрос в том, почему вам нужно структурировать свой код, как это, и почему вы не можете структурировать его таким образом, чтобы он работал на ожидаемое поведение. Это ваш код или кто-то elses? Если это ваш код, вы не можете изменить свой подход/дизайн? –

ответ

1

B() {super.a1 = new B1 (this); } // FAIL: конечное значение изменения can not

Вы не можете назначать значения уже назначенным конечным переменным, вы можете создать экземпляр внутри конструктора, но не следующим образом.

B() {супер (новый B1 (это));} // FAIL: не могу использовать 'это' или 'супер'

Вы можете использовать этот раз экземпляр создается только. Так как дерево наследования, он не полностью инстанцирован, поэтому компилятор жалуется,

не может ссылаться на это раньше супертип конструктор был назван

+0

Я не могу сделать это таким образом, который я раскрыл, но мне нужно сделать это каким-то образом, чтобы не нарушить функциональность ограничения доступа. Поэтому я пытаюсь найти другой способ, который не включает защиту от отражения. –

1

С this tip, задаваемым @KevinHooke, я нашел это answer и я пришел с этим кодом ниже.

Но имейте в виду, что этот вариант я выбрал may cause trouble.

Таким образом, я закончил использование метода overriden для создания экземпляра типа «1», позволяя суперклассу выполнять задание.

class finalFieldTestWorks{ 
    class A1{A1(A a){}} 

    class A{ 
     protected final A1 a1; 
     A(){ 
     this.a1=new1(); 
     } 
     protected A1 new1(){return new A1(this);} 
    } 

    class B1 extends A1{B1(B b){super(b);}} 

    class B extends A{ 
     B(){ 
     super(); 
     } 
     @Override 
     protected B1 new1(){return new B1(this);} 
    } 
} 

PS .: Другие рекомендации/обходные пути будут оценены.

 Смежные вопросы

  • Нет связанных вопросов^_^