如何让两个类共享相同的变量定义?

时间:2021-07-06 21:00:10

What I really need is to be able to declare regular variables in an interface and implement that interface in two classes that I would not have to have to re-declare these in each class (ie class.data.variables instead of class.variables). Is there any way that I could achieve the same goal differently?

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

To give more detail. Essentially, I have created a small drawing program that drops JLabels on a JPanel that is on a JScrollPane. Because I have a specific design for these JLabels (ie they are not just for drawing they represent airline objects for this application), I have a class that extends JLabel and adds my application specific variables to it. Ultimately, I read and write an XML file with these variables so they can load and save their designs. Since I can not use this extended class for my XML definitions because it screams about the parent class even though I told it to have NONE as the accessor (I read there is a bug), I have to create an identical class and copy values back and forth for saving and loading. Not too much of a problem except when I add a variable to the JLabel extended class and forget to add it to the XML mimic class and subsequent copy routines.

给更多的细节。本质上,我创建了一个小绘图程序,它将jlabel放在JScrollPane中的JPanel上。因为我对这些JLabel有一个特定的设计(它们不只是为这个应用程序绘制它们代表的航空对象),我有一个扩展JLabel的类,并将我的应用程序特定变量添加到它。最后,我用这些变量读取和编写一个XML文件,以便它们可以加载和保存它们的设计。因为我不能使用这个扩展类我对父类的XML定义,因为它尖叫即使我告诉它没有作为访问器(我读到有一个错误),我要创建一个相同的类和来回复制值保存和加载。问题不大,除非我向JLabel扩展类添加了一个变量,而忘记将它添加到XML模拟类和后续的复制例程中。

So, it would be great if I could make one class (say CellDataRecord.java) that held the extra data declarations and have that class be used in both places (the JLabel extension and the XML data) without having to have something like XML.data.CellDataRecordXXX.

因此,如果我可以创建一个包含额外数据声明的类(比如CellDataRecord.java),并且在两个地方(JLabel扩展和XML数据)都使用该类,而不需要使用类似于XML.data. celldatarecordxxx的东西,那就太好了。

2 个解决方案

#1


5  

You can do that with inheritance or using an interface, where the variable is set as a constant in the parent class. Since you are extending a JLabel, you should implement the interface on both classes:

您可以通过继承或使用接口来实现这一点,其中将变量设置为父类中的常量。由于您正在扩展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`
}

Edit

Since you want to be able to change the same variable from different classes, you have to ensure you aren't changing copies and are changing the same variable, so you should use a volatile keyword on the variable to indicate to java that all threads should check the value before it updates it.

因为你希望能够改变从不同类型相同的变量,你必须确保你不改变副本和正在改变相同的变量,所以您应该使用挥发性的变量来表示java关键字之前应该检查所有线程值更新它。

Now you'll need to have a separate class so that instances can be made from other classes to get the value. You have to use the static keyword to ensure that one copy is kept for all class instances.

现在需要有一个单独的类,以便可以从其他类中创建实例来获取值。您必须使用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; }
}

Now the other two classes just do this:

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

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);
    }
}

Now you can do this:

现在你可以这样做:

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

#2


1  

I'm not sure I 100% grasp your problem but from the first few lines of your description, instead of implementing an interface, you could define an abstract class and have your classes extend it. That way, you'll be able to define attributes in the abstract class and these will be common to all subclasses.

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

#1


5  

You can do that with inheritance or using an interface, where the variable is set as a constant in the parent class. Since you are extending a JLabel, you should implement the interface on both classes:

您可以通过继承或使用接口来实现这一点,其中将变量设置为父类中的常量。由于您正在扩展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`
}

Edit

Since you want to be able to change the same variable from different classes, you have to ensure you aren't changing copies and are changing the same variable, so you should use a volatile keyword on the variable to indicate to java that all threads should check the value before it updates it.

因为你希望能够改变从不同类型相同的变量,你必须确保你不改变副本和正在改变相同的变量,所以您应该使用挥发性的变量来表示java关键字之前应该检查所有线程值更新它。

Now you'll need to have a separate class so that instances can be made from other classes to get the value. You have to use the static keyword to ensure that one copy is kept for all class instances.

现在需要有一个单独的类,以便可以从其他类中创建实例来获取值。您必须使用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; }
}

Now the other two classes just do this:

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

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);
    }
}

Now you can do this:

现在你可以这样做:

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

#2


1  

I'm not sure I 100% grasp your problem but from the first few lines of your description, instead of implementing an interface, you could define an abstract class and have your classes extend it. That way, you'll be able to define attributes in the abstract class and these will be common to all subclasses.

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