【问题标题】:Java: Call a method from a "contained" classJava:从“包含”类调用方法
【发布时间】:2011-09-26 15:28:15
【问题描述】:


我有一个这样的类层次结构:

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!!!
             */
        }
    }
}

是否可以在该位置从 B 类调用 A 类的方法?

问题是我在 A 中有一个 B 对象列表,每当在其中一个 B 对象中单击按钮时,都必须在 A 中进行更改。

谢谢!

【问题讨论】:

    标签: java class call


    【解决方案1】:

    不存在允许您从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();
            }
        }
    

    【讨论】:

    • 那个下划线让我的眼睛流血了:/。严肃地说,您必须将 method1 更改为 public。
    【解决方案2】:

    没有。您需要从 B 类中引用回 A 的实例。

    【讨论】:

    • 并非如此。如果 A 中有 B 列表,您可以在 A 中定义 MouseListener 并将其添加到每个 B。
    • 当然。但是你仍然不能从 B 调用到 A,除非你在 B 中有对 A 的引用
    【解决方案3】:

    是的,你必须有一个参考(如前所述)。

    我只是在这里添加提到这可能会有点棘手。如果可以的话,我建议重新设计你的结构,这样你就不需要双重引用,如果不是,我强烈建议你不要尝试在构造函数中进行设置——而是调用 a.init(b) 和/或 b.init(a) 设置值。

    它现在可能会像写的那样工作,但随着时间的推移,在构造函数中初始化会导致越来越多的限制和挫败感。并不是说您以后不能重构,但我想我只是建议您这样做,这样您就不会在决定重构之前浪费太多时间敲脑袋。

    如果您考虑一下,这样做会使您无法仅实例化其中一个,从而使测试变得更加困难,并且如果您在类的构造中添加任何其他依赖项,则可能变得不可能(这开始达到与多重继承相同的复杂性)。

    您可能还需要考虑将自己作为侦听器添加到公共源或使用事件总线(可能是最干净和最简单的解决方案)。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-09-04
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-07-01
      相关资源
      最近更新 更多