I am working on a projects and I have run into a problem, I don't know the best way to share updated data between classes. The current way that I am doing this is by having a static instance of my class in it and having all the other classes change the instance and not the original class.
public class A{
public static volatile instance;
public B b = new B();
public C c = new C();
public D d = new D();
public A(){
this.instance = this;
b.changeData();
}
}
public class B{
public void changeData(){
A.instance.d.changeSomethingInD();
}
}
Now, all the changes that D made to its variables can be accessed by B and C. Is there a better way to do this?
Edit 1: The problem that I have is having updated variables accessible to all the other classes. This was what I was doing before:
public class MainClass extends JavaPlugin{
private RegionLoader rLoader;
private ClassesLoader cLoader;
private MessageHandler mHandler;
private PlayerDates pDates;
public MainClass(){
dirMaker();
mHandler = new MessageHandler(this);
pDates = new PlayerDates(this);
cLoader = new ClassesLoader(this);
rLoader = new RegionLoader(this);
}
//getters and setters
}
But the problem is if the RegionLoader changes somithing within itself, the ClassesLoader won't have the updated variables and will work with the old ones, or would it?
Why not just pass A into the constructor of B. This way you wouldn't need to use static data.
public class A{
public B b;
public C c = new C();
public D d = new D();
public A(){
b = new B(this);
b.changeData();
}
}
public class B{
private A a;
public B(A a){
this.a = a;
}
public void changeData(){
a.d.changeSomethingInD();
}
}
You could also checkout the observer pattern.
Related
I have 2 class, class B and A
public class B
private Car fiat;
public boolean trueOrFalse() {
return fiat.methodFromClassCar();
}
In class A i want to use this result from this boolean, something like:
public class A
public int xyz(){
if (trueOrFalse()==true){
doSomething();
}
}
Always i making static all, but now i cant do this. Is there better way ?
Create a new object in class A:
Car cr = new Car();
and then using
cr.trueOrFalse();
is good way ? but what i code wrong here ?
You have different options :
-> have a Car as attribute of class A
public class A{
private Car c;
public int xyz(){
if (c.trueOrFalse()){ //==true is 100% useless
doSomething();
}
}
}
call with A test = new A(); /*then*/ test.xyz(); //c = new Car(); in constructor of A
-> give to the method a Car as parameter
public class A{
public int xyz(Car c){
if (c.trueOrFalse()){
doSomething();
}
}
call with A test = new A(); /*then*/ test.xyz(new Car()); or Car c = new Car(); /*then*/test.xyz(c);
I have 2 classes that rely on each other and they both have their respective interfaces. However, I cannot setup the constructor on both classes cleanly. In short, one class needs to be instantiated before the other class gets instantiated.
Class A implements IA {
public A(IB b) {
myBclass = b;
}
private IB myBclass;
}
Class B implements IB {
public B(IA a) {
myAclass = a;
}
private IA myAclass;
}
static void main(String[] args) {
A a = new A(null);
B b = new B(a);
a.setB(b); // how can I avoid doing this
}
I would like to avoid setting member variables outside the constructor.
You can have one construct the other.
class A implements IA {
private IB myBclass;
public A() {
myBclass = new B(this);
}
// etc.
}
class B implements IB {
private IA myAclass;
public B(IA a){
myAclass = a;
}
// etc.
}
That way you don't have to alter them after construction.
public static void main(String[] args){
A a = new A();
B b = a.getB();
}
I have a class C with lots of members(say 10 members) + members that are only in C
I have two more classes A and B which has exactly those above mentioned 10 members. (A and B each does not have those 10 members. Those 10 members are distributed among A and B and A and B has few other fields)
class C {
private int member1;
private String member2;
private String member3;
private float member4;
...
private String member10;
private member11_only_in_C;
private member12_only_in_C;
...
}
class A {
private String memeber10;
private float member4;
private double member6;
....
}
class B {
private int memeber1;
private String memeber2;
private String member7;
....
}
So when I have cObject I need to set the values of all members in A and B like
aObject.setMember10(cObject.getMember10());
bObject.setMember1(cObject.getMember1());
... and so on for all 10 members
This looks bad(long and in future If i add more members to C,A,B I need to write setters for them). So what I thought was If I have class C extend or implement A and B I can cast it like
A aObject = (A)cObject;
B bObject = (B)cObject;
But the problems are
Java does not allow multiple inheritance
I cannot make A and B as interfaces because I need to set their values. (If I make them as interfaces, their members would become final, which means that I cannot change their values)
I cannot extend one class and implement other. (I then cannot set values of members of the interface)
What can I do now?
Thanks..
As I understand it you have two classes A and B, both with a number of fields, and you want to create a third class C with all the fields of A and B.
As you point out you can't do this with inheritance in Java because multiple inheritance of state is not supported.
You can do something similar using composition instead.
public final class C {
private final A a;
private final B b;
public C(A a, B b) {
this.a = a;
this.b = b;
}
...
void setMember7(String s) {
b.setMember7(s);
}
String getMember7() {
return b.getMember7();
}
...
}
I'm not sure if this is a good idea or what you need though. We would need more information about your use-case.
EDIT
If A and B have fields that are not in C you could make a class A2 with all the fields common to A and C and a class B2 with all the fields common to B and C, like this:
public final class A {
private final A2 a2;
// other fields
public A(A2 a2) {
this.a2 = a2;
}
}
public final class B {
private final B2 b2;
// other fields
public B(B2 b2) {
this.b2 = b2;
}
}
public final class C {
private final A2 a2 = new A2();
private final B2 b2 = new B2();
...
public void setMember7(String s) {
b2.setMember7(s);
}
public String getMember7() {
return b2.getMember7();
}
...
public A getA() {
return new A(a2);
}
public B getB() {
return new B(b2);
}
}
I don't know exactly what you want but i think what you need can be accomplished in the constructor
Class A{
private member1;
private member10;
Class A(){
}
Class A(C cObject){
member1 = cObject.getMember1();
//the rest of member varaibles you want to set
member10 = cObject.getMember10();
}
}
Class B{
private member1;
private member10;
Class B(){
}
Class B(C cObject){
member1 = cObject.getMember1();
//the rest of member varaibles you want to set
member10 = cObject.getMember10();
}
}
to use it :-
B objectB = new B(objectC);
A objectB = new A(objectC);
I have three classes.
Class A extends jFrame (Which is the main user interface)
Class B extends jPanel (This one is called to appear inside of the main jFrame)
and Class C to do some file handling and processing.
What I am trying to do is have an object of Class C instantiated in Class A and calling it in Class B.
Here's some sample code:
Public Class A extends javax.swing.JFrame {
Public A(){
C ObjectOfC = new C();
B panelWithButtons = new B();
}
}
public Class B extends javax.swing.JPanel{
String s = ObjectOfC.getName();
}
public Class C{
String name;
public String getName(){
return this.name;
}
}
Is there anyway to get this done? or is it a lost cause?
There are a number of ways to do this, depending on what you are trying to accomplish. You probably want to build either a constructor or a method for B that takes object C as an argument.
Example:
Public Class A extends javax.swing.JFrame {
Public A(){
C objectOfC = new C();
B panelWithButtons = new B(objectOfC);
}
}
public Class B extends javax.swing.JPanel{
String s;
public B (C objectOfC) {
this.s = objectOfC.getName();
}
}
public Class C{
String name;
public String getName(){
return this.name;
}
}
A singleton example as per your comment:
Public Class A extends javax.swing.JFrame {
Public A(){
B panelWithButtons = new B();
}
}
public Class B extends javax.swing.JPanel{
String s;
objectOfC C = C.getInstance();
this.s = objectOfC.getName();
}
public class C {
private static String name;
private static final C INSTANCE = new C();
private C() {}
public static C getInstance() {
return INSTANCE;
}
public static String getName() {
return this.name;
}
}
A singleton example with changing variables (and errors removed from the original code.):
public class A extends javax.swing.JFrame {
public A() {
C objectOfC = C.getInstance();
objectOfC.setName("Bob");
B panelWithButtons = new B(objectOfC);
System.out.println("objectOfC_A:" + objectOfC.getName()); //return "George"
}
}
public class B extends javax.swing.JPanel {
public B (C objectOfC) {
C c2 = C.getInstance();
objectOfC.setName("Fred");
c2.setName("George");
System.out.println("objectOfC_B:" + objectOfC.getName()); //returns "George"
System.out.println("c2: " + c2.getName()); //returns "George"
}
}
public class C {
private static String name;
private static final C INSTANCE = new C();
private C() {}
public static C getInstance() {
return INSTANCE;
}
public String getName() {
return C.name;
}
public void setName (String name) {
C.name = name;
}
}
With this example you can call C.getInstance from any class and they will all be sharing the same instance. However, you must be careful with how you are going to access the object; there are plenty of tutorials out there about multithreading singletons which you will need to do if you plan on modifying data in the C instance from multiple objects at the same time.
Suppose I have a class A and a class B.
public class A {
private B b;
public A() {
this.b = new B();
}
public B getB() {
return this.b;
}
}
public class B {
public String getSome() {
return "Get some!";
}
}
I know I can get B through A, because A has (or owns) B: new A().getB().
But if I have B, can I get A?
Sure, just add routine getA() in you class B, and change the line in your constructor to
public A() {
this.b = new B(this);
}
This of course assumes your class B has a constructor which accepts an A, e.g.,
public B(A a) {
this.a = a;
}
B needs an explicit reference to its owner:
public class B {
private final A owner;
public B(A owner) {
this.owner = owner;
}
public A getOwner() {
return owner;
}
}
And in A:
public A() {
b = new B(this);
}
Nope. There is no such thing as an 'owner' in Java. Any object can be referenced by any number of other objects.
If you need B to always be bound to an instance of A, make B an inner class of A:
class A {
B b = new B();
class B {
String getSome() {
// this will refer to the enclosing A
return A.this.toString();
}
}
}
An inner (non-static) class always has an implicit reference to the enclosing instance and cannot exist without it. In order to instantiate B from outside, you need a nasty syntax: B b = new A().new B();
No you cannot. B has no reference to A.
No.
Class a has reference to class B, but class B has no reference to class A. References are one way only.
No, that's not possible. You're looking for backreferences, but we have to create them in the code if needed.
If you want to collect all referencers to B, you could do this with a constructor or with a factory (pattern) that creates B's. I'll show the factory:
public class B {
private static Set<? extends Object> referencers = new HashSet<? extends Object>();
private B(){} // no public constructor
public static create(Object parent) {
// cooperative approach, the caller should pass "this"
referencers.add(parent);
}
public static remove(Object parent) {
referencers.remove(parent);
}
}
you can also use inner classes
package test;
public class A {
B b = null;
public B getB()
{
return b;
}
public class B {
public A getA()
{
return A.this;
}
}
public static void main(String[] args) {
B b = new A().new B();
}
}