【问题标题】:How can I have two classes share the same variable definitions如何让两个类共享相同的变量定义
【发布时间】:2012-05-17 22:47:10
【问题描述】:

我真正需要的是能够在接口中声明常规变量并在两个类中实现该接口,我不必在每个类中重新声明它们(即 class.data.variables 而不是 class .变量)。有什么方法可以让我以不同的方式实现相同的目标?

提供更多细节。本质上,我创建了一个小型绘图程序,将 JLabels 放在 JScrollPane 上的 JPanel 上。因为我对这些 JLabel 有一个特定的设计(即它们不只是用于绘制它们代表此应用程序的航空公司对象),所以我有一个扩展 JLabel 并将我的应用程序特定变量添加到它的类。最终,我用这些变量读写了一个 XML 文件,这样他们就可以加载和保存他们的设计。由于我不能将这个扩展类用于我的 XML 定义,因为它对父类尖叫,即使我告诉它有 NONE 作为访问器(我读到有一个错误),我必须创建一个相同的类并将值复制回来来回保存和加载。问题不大,除非我将变量添加到 JLabel 扩展类并忘记将其添加到 XML 模拟类和后续复制例程中。

所以,如果我可以创建一个包含额外数据声明的类(比如 CellDataRecord.java)并让该类在两个地方(JLabel 扩展和 XML 数据)都使用,而不必拥有一些东西,那就太好了比如 XML.data.CellDataRecordXXX。

【问题讨论】:

  • 您所描述的将被称为 mix-in——而 Java 没有这些。您必须使用您已经熟悉的一种或另一种模式。
  • 和我的问题一样。

标签: java xml swing oop


【解决方案1】:

您可以通过继承或使用接口来做到这一点,其中变量在父类中设置为常量。由于您正在扩展 JLabel,因此您应该在两个类上实现接口:

public interface MyInterface {
    int someint = 9;
}

public class MyClass1 extends JLabel implements MyInterface {
    //this class has access to `someint`
}

public class MyClass2 extends JLabel implements MyInterface {
    // also has access to `someint`
}

编辑

由于您希望能够从不同的类更改相同的变量,因此您必须确保您没有更改副本并且正在更改相同的变量,因此您应该在变量上使用 volatile 关键字来指示java 所有线程都应该在更新它之前检查该值。

现在您需要有一个单独的类,以便可以从其他类中创建实例来获取值。您必须使用static 关键字来确保为所有类实例保留一份副本。

public class MyVariableWrapper {
    public static volatile int some_var = 9;
    public void updateSomeVar(int newvar) {
         some_var = newvar;
    }
    public int getSomeVar() { return some_var; }
}

现在其他两个类就是这样做的:

public class MyClass1 extends JLabel {
    MyVariableWrapper myVariableWrapper;
    MyClass1() {
        super();
        myVariableWrapper = new MyVariableWrapper();
        // now I have access to `some_var`
    }
}

public class MyClass2 extends JLabel {
    MyVariableWrapper myVariableWrapper;
    MyClass2() {
        super();
        myVariableWrapper = new MyVariableWrapper();
        // now I have access to the same `some_var` as MyClass1
    }

    // this is a wrapper method for your convenience
    // since you don't like the excess code when accessing the variable
    public int getSomeVar() {
        return myVariableWrapper.some_var;
        // or myVariableWrapper.getSomeVar();
    }
    public void setSomeVar(int newvar) {
        myVariableWrapper.some_var = newvar;
        // or myVariableWrapper.setSomeVar(newvar);
    }
}

现在你可以这样做了:

MyClass2 myClass2 = new MyClass2();
System.out.println(""+myClass2.getSomeVar());

【讨论】:

  • 我的理解是,如果我使用一个接口,那么我所有的“变量”都会变成“常量”,我需要它们成为变量。所以,如果我理解正确,界面将不适合我。
  • @JesterHawk 哦,对了,你只需要在自己的类中声明变量为static 和volatile,然后从需要该变量的两个类中创建该类的实例。以下是在 java 中使用 volatile 变量的示例:ilkinbalkanay.blogspot.co.uk/2007/10/…
  • 好的,那么要使用 some_var,我必须执行类似 myVariableWrapper.some_var 之类的操作,对吗?
  • @JesterHawk 因为它是静态的,是的。但是你也可以像我在上面的例子中那样使用 getter/setter
  • 这是我希望避免的。我知道我可以在其他类中实例化原始类。但是当我引用时,我将不得不做 subclass1.data.originalclassvariable 之类的事情。我希望在没有“.data”的情况下做到这一点。部分是因为我已经编写了太多代码,不得不返回并全部更改。这就是为什么我想知道是否有一种方法可以基本上拥有一个实际上有变量的接口。
【解决方案2】:

我不确定我是否 100% 理解您的问题,但从您描述的前几行来看,您可以定义一个抽象类并让您的类扩展它,而不是实现接口。这样,您就可以在抽象类中定义属性,并且这些属性对所有子类都是通用的。

【讨论】:

  • 是的,问题在于它扩展了 JLabel,因为我需要在 JPanel 上绘制它的能力。而且由于我不能让一个类同时扩展 JLabel 和一个抽象类(这实际上很酷而且很有帮助),所以这是行不通的。
  • 我确实尝试将 JLabel 作为类的一个组件,但在绘图部分遇到了问题。可能是我知识不够。但基本上我在删除时遇到了问题。例如,用户将鼠标悬停并单击以删除包含 JLabel 的“单元格”。我可以将它从窗格中删除,但发现它在 ArrayList 中的哪个“单元格”证明是不稳定的。我正在检查组件,但它并不总是找到它。因此,我没有可靠的方法从 JPanel 和 ArrayList 中删除“单元格”。同样,可能是我缺乏知识。
  • @JesterHawk 但你可以实现任意数量的接口
  • @Ozzy,是的,但是如果我理解正确的接口只会给我常量,对吗?如果是这样,那将不起作用,因为我需要变量。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-12-20
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-07-28
  • 1970-01-01
相关资源
最近更新 更多