Java: вызов метода из содержащегося класса


У меня есть такая иерархия классов:

public class A {

    private B obj = new B();   // Inside this object 
                               // do I need a reference to here?
                               // (In order to call method1())

    public A(){    ...    }

    private void method1(){    ...    }
    private void method2(){    ...    }
}

// Other package
public class B {
    private JButton bt1 = new JButton("Button");

    public B(){
            ...
        bt1.addMouseListener(new MouseActionsListener(this));
    }

    public class MouseActionsListener implements MouseListener
    {
        @Override
        public void mouseClicked(MouseEvent event)
        {
            /*
             * I need to call method1() HERE!!!
             */
        }
    }
}

Можно ли в этой позиции вызвать метод класса A из класса B?

Проблема в том, что у меня есть список объектов B в A, и всякий раз, когда нажимается кнопка в одном из объектов B, необходимо внести изменения в A.

Благодарю вас!


person Gino Cappelli    schedule 26.09.2011    source источник


Ответы (3)


Нет неявной ассоциации, которая позволила бы вам перейти от B к A.

Вам нужно будет:

  • измените B, чтобы сохранить ссылку на соответствующий экземпляр A;
  • инициализировать эту ссылку в конструкторе B;
  • используйте его, вызовите методы A.

В коде:

public class A {

    private B obj;

    public A() {
        obj = new B(this);
        ...
    }

    public void method1(){    ...    }
    public void method2(){    ...    }
}


public class B {

    private final A _a;

    public B(A a) {
        _a = a;
    }

    public class MouseActionsListener implements MouseListener
    {
        @Override
        public void mouseClicked(MouseEvent event) {
            _a.method1();
        }
    }
person NPE    schedule 26.09.2011
comment
От этого подчеркивания у меня глаза кровоточат :/. Если серьезно, вы должны изменить метод1 на общедоступный. - person pablochan; 26.09.2011

Нет. Вам понадобится ссылка на экземпляр A из вашего класса B.

person Adam Batkin    schedule 26.09.2011
comment
Не совсем. Если в A есть список B, вы можете просто определить MouseListener в A и добавить его к каждому B. - person pablochan; 26.09.2011
comment
Конечно. Но вы по-прежнему не можете звонить из B в A, если у вас нет ссылки на A в B. - person Adam Batkin; 26.09.2011

Да, у вас должна быть ссылка назад (как уже было сказано).

Я только добавляю здесь, чтобы упомянуть, что это может стать немного липким. Если вы можете, я предлагаю перепроектировать вашу структуру, чтобы вам не требовалась двойная ссылка, если нет, я настоятельно рекомендую вам не пытаться выполнять настройку в конструкторах - вместо этого вызовите a.init(b) и/ или b.init(a) для установки значений.

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

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

Вы также можете рассмотреть возможность добавления обоих в общий источник в качестве слушателей или использования шины событий (вероятно, самое чистое и простое решение).

person Bill K    schedule 26.09.2011