I would like to make an object of a class A and it is initialized in class B, class C, and class D
This object should be shared; that is if any changes made to objA in these classes(C and D), its content remains the same even after objC,'objD' are destroyed, supposely that class B is the main class. I would like to use its property is class B
class A {}
class B
{
initialize class A object and use-change its property
initialize class C object and use-change its property
initialize class D object and use-change its property
}
class C{initialize class A object and use-change its property}
class D{initialize class A object and use-change its property}
class X{initialize B and destroy objC,objD, from objB use property of objA of class B}
A non static attempt would look like this:
Your target object:
public class A {
}
Your classes, that do something with the object:
public class C {
private final A a;
public C(final A a) {
this.a = a;
}
public foo() {
// do something with a
}
}
public class D {
private final A a;
public D(final A a) {
this.a = a;
}
public otherFoo() {
// do something with a
}
}
Your main class:
public class B {
public static void main(String[] args) {
final A a = new A();
final C c = new C(a);
final D d = new D(a);
c.foo();
d.otherFoo();
}
}
Try making the object static that way any changes made to one instance of that object will be consistent across all objects that use that object that are in the same thread.
This is essentially a singleton pattern, you can pass your class around or get it from the main. I prefer the latter personally, like so:
public class YourMain {
private final ClassA clazzA;
private final ClassB clazzB;
private final ClassC clazzC;
private final ClassD clazzD;
public YourMain() {
this.clazzA = new ClassA();
this.clazzB = new ClassB(this);
this.clazzC = new ClassC(this);
this.clazzD = new ClassD(this);
this.clazzB.doSomething();
}
public ClassA getClassA() {
return this.clazzA;
}
}
From there, you can chain back up to your main class in the other classes:
public class ClassB {
private final YourMain project;
public ClassB(YourMain project) {
this.project = project;
}
public void doSomething() {
this.project.getClassA().someMethod();
}
}
Of course, this isn't 100% what you would implement it like (you need to mind the order you load things in if you are passing your main class instance), but for something like this I usually find it is the cleanest and provides the easiest availability to all my classes across a project.
Related
I have 2 classes, and I have made one class (Class A) instantiate a Class B object.
I have a method in Class B that I want to call a method in Class A.
I'm working on a larger project for practicing Java, so I am simplifying things here.
// Class A:
public class ClassA {
private int number;
private ClassB instanceOfB = new ClassB();
public ClassA {
number = 0;
}
public void incrementNumber {
number++;
}
public void incrementNumberLongWay {
instanceOfB.incrementNumberInA()
}
}
// Class B:
public class ClassB {
public void incrementNumberInA() {
// My desire: Call Class A's incrementNumber method
// What should I put here?
}
}
How do I make sure incrementNumberLongWay works? Class A has been instantiated, and it's method incrementNumberLongWay is called, so this should call ClassB's method incrementNumberInA
I know this seems extremely convoluted, but the reason I'm doing this, is because in my program I'm not incrementing numbers, but instead doing some logic in Class B, and only wanting to affect Class A in certain cases.
You can't do this with the code provided. Relationships are by default one way. B doesn't know about A so cannot access it.
What you can do is pass a reference of A to B in it's construction process and then access A via that reference.
One solution would be to pass a method of A as a callback.
For example:
public class ClassA {
private int number;
private ClassB instanceOfB = new ClassB();
public ClassA {
number = 0;
}
public void incrementNumber {
number++;
}
public void incrementNumberLongWay {
instanceOfB.incrementNumberInA(this::increment);
// alternatively
// instanceOfB.incrementNumberInA(() -> incrementNumber());
}
}
public class ClassB {
public void incrementNumberInA(Runnable callbackMethod) {
callbackMethod.run();
}
}
This removes B's dependency on A, and instead allows a general callback mechanism.
However, for such a simple scenario this approach isn't advised.
It's probably a bad idea in general to have a circular dependency in this way. One approach to break the cycle would be to have a third class (classC?) that implements the increment logic (or whatever your real-world equivalent is), and have classA and classB instances each reference classC. That way there's no case where two classes know about each other.
ClassB doesn't know anything about ClassA. So, you couldn't do it.
The ugly decision is
public void incrementNumberLongWay() {
instanceOfB.incrementNumberInA(this);
}
and in
public class ClassB {
public void incrementNumberInA(ClassA cl) {
cl.incrementNumber();
}
}
You can't call methods from class A from class B as class B has no reference to an object of class a. You could, however, pass class A's current number state to class B as parameter, and return a value from class B which class A can then get and use.
For example:
public class A {
private int number;
public A(int number) {
this.number = number;
}
public void incrementNumber(boolean largeIncrement) {
if(largeIncrement) {
B bInstance = new this.B();
number = bInstance.incrementNumberLongWay(number);
}
else {
number++;
}
}
private class B {
private B() {
// if some initialization is needed...
}
public int incrementNumberLongWay(int num) {
num += 1000;
return num;
}
}
}
Hope this is what you wanted.
Being new to Java but an old hand on older procedural languages and structured programming, I have a question on how to accomplish something in Java
I have three classes, let's say they're called CLASSA, CLASSB, and TESTCLASSA. CLASSA has a class definition with instance variables, and a constructor for some data. TESTCLASSA creates an instance of CLASSA and passes data to CLASSA by creating an instance of the object for CLASSA. SImiliarly CLASSB has another class definition with instance variables, and a constructor for some data. TESTCLASSA creates an instance of CLASSB and passes data to CLASSB by creating an instance of the object for CLASSB. I am trying to access CLASSB's data from CLASSA. Can someone suggest how I might go about doing this. Many thanks in advance for any assistance/suggestions you can provide.
Wayne Hann
Either declare the variable as public:
public class classA {
public Integer data;
}
or create a public getter (preferred), such as:
public class classA{
private Integer data;
public Integer getData() {
return data;
}
}
If you want to access properties of class B from class A then it's either possible that you create a object of B in the method from where you want to getData like
private String nameofA;
public String getNameofA() {
return nameofA;
}
public void setNameofA(String nameofA) {
this.nameofA = nameofA;
}
public String getClassBData(){
B b = new B();
return b.getNameofB();
}
else you create a class level instance or dependency of B type.
public class TestClassA{
public static void main(String[] args) {
B b = new B();
b.setNameofB("class B Name");
A a = new A("class A Name",b);
}
}
class A{
private String nameofA;
private B b = new B(); //either this
public String getNameofA() {
return nameofA;
}
public A(String nameofA, B b) {//or constructor
super();
this.nameofA = nameofA;
this.b = b;
}
public void setNameofA(String nameofA) {
this.nameofA = nameofA;
}
public String getClassBData(){
B b = new B(); // or creating local instance
//but here a new instance will be created
return b.getNameofB();
}
}
Then only you will be able to access the data of instance of B. Anyway you if your method in B is not private or protected(assuming A doesn't extend B), you can access the method by creating or passing a instance of B to the method of "A" from where you want to access.
I want to design a class which should return a singleton of some third party object.
For e.g., I want to create a singleton of 3rd party B class object. Below is the design I have made.
public class A{
private static A A = null;
private static B B = null;
private A() {
B = code to instantiate B Object;
}
public static synchronized A getAInstance() {
if(A ==null){
synchronized(A.class){
if(A == null){
A = new A();
}
}
}
return A;
}
public B getB(){
return B;
}
}
Can you please help me is this a proper singleton
If I understand your question correctly, you want to have a single instance of a third party class. First of all it is a good practice to access third party obj via wrapper class obj,(clean code handbook of agile software craftsmanship chapter8), in your case class b is wrapped by class a.
In order to make a single instance of class b you can just make it an instance variable of class a and then make the class a singleton, code bellow
Public class A{
private static A A = null;
private B B = null;
private A() {
B = code to instantiate B Object;
}
public static synchronized A getAInstance() {
if(A ==null){
synchronized(A.class){
if(A == null){
A = new A();
}
}
}
return A;
}
public B getB(){
return B;
}
}
You can simply have this structure. No explicit synchrnoization required, just leave it to JVM.
public class A {
private static class BInstanceHolder {
B BInstance = new B();
}
private A(){}
public static B getB(){
return BInstanceHolder.BInstance;
}
}
If you only want to have one copy of B, just do it that way!
You dont even need a Singleton of Class A.
So you could try:
public final class A{
private A(){}
private static B instance;
static{
instance = code to instantiate B Object
}
public static synchronized B getInstance() {
return B;
}
}
The static Block will create a instance of B when the Class is first mentioned and will instantiate the instance. The constructor will prevent the A from being made, but you can still access the only instance of B.
I am thinking of an optimum design pattern which I can use to transfer objects to the methods in different classes other than passing them as arguments.
class A{
}
class B{
public A a;
public B()
{
a = new A();
}
}
class C
{
public void c()
{
//need to access "a" of class B other than passing "a" as argument;
}
}
Here, a in class A attribute needs to be accessed in many other class methods. Is there an optimum design pattern or any possible way other than passing this object (a) as arguments?
It's hard to say how your program is really structured but two options come to mind:
Pass an instance of B to C's constructor.
class A {};
class B {
public A a;
public B() {
a = new A();
}
};
class C {
public B b;
public C( B b ) {
this.b = b;
}
public void someMethod() {
System.out.println( b.a );
}
};
If only one instance of class A ever exists (ie a Singleton). That means that class B holds an instance of class A, not each instance of class B holds an instance of class A.
class A {};
class B {
public static final A a = new A();
};
class C {
public void someMethod() {
System.out.println( B.a );
}
};
i Have a class G which will make instance of the classes Like A B C D each classes are in different packages,
While making instance of the A B C D each has different factory methods because arguments are different.
and no other classes can call the factory method of these A B C D classes.
Is any way to do this?
Lets Assume that you have
CLASS B
package com.b;
import com.g.ClassG;
public class ClassB {
private ClassB(int arg1,String arg2){
}
public static ClassB getInstance(Object object) throws Exception {
if(object instanceof ClassG) {
return new ClassB(1, "Shree");
}else {
throw new Exception("instance creation is Only supported for ClassG");
}
}
}
CLASS A
package com.a;
import com.g.ClassG;
public class ClassA {
private ClassA(int arg1){
}
public static ClassA getInstance(Object object) throws Exception {
if(object instanceof ClassG) {
return new ClassA(1);
}else {
throw new Exception("instance creation is Only supported for ClassG ");
}
}
}
Then If you write your class G as below
CLASS G
package com.g;
import com.a.ClassA;
import com.b.ClassB;
public final class ClassG {
public static void main(String args[]) throws Exception {
ClassG gObject = new ClassG();
ClassA aObject = getClassAInstance(gObject);
ClassB bObject = getClassBInstance(gObject);
}
private static ClassB getClassBInstance(ClassG gObject) throws Exception {
return ClassB.getInstance(gObject);
}
private static ClassA getClassAInstance(ClassG gObject) throws Exception {
return ClassA.getInstance(gObject);
}
}
I think above solution would be sufficient for you .
restriction of instance creation is put in factory method
Class G is final hence There would not be any way to create ClassA and ClassB instances except Class G
Let me know your feedback on this
The proper way to do this is to make these classes only have package-private constructors, and only the factories be public.
Packages are the only real way in Java to specify access permissions for related classes.
You'd have to put them all in the same package, though.
One hacky workaround could be to have your factory methods take a G instance as a parameter (and check that it is not null), and make it impossible to create G instances from any other place then G itself.
public class G {
private G (){} // no one can make G instances
public static A makeA(){
return A.publicFactoryThatNeedsG( new G(), theRealParameters);
}
}
Very ugly.
In particular, ties A,B,C,D to G.