What is better : passing an object through a constructor and save it to new reference in another class, or passing through a constructor an directly pass it to method? Is there any difference?
class A
{
int a;
int b;
}
class B
{
public A refA;
public B(A refA)
{
this.refA = refA;
methodInB(refA);
}
public void methodInB(A refA)
{
...
}
}
OR -------------------------------------------------- OR
class A
{
int a;
int b;
}
class B
{
public B(A refA)
{
methodInB(refA);
}
public void methodInB(A refA)
{
...
}
}
It depends on whether A is integral part of B or not same goes for the methodInB. If we don't put A's reference in B then methodInB becomes kind of a utility method, which should better be static. If it's not a utility then it has a dependency on A and A's reference should be put in B.
Also if there are other methods in B which may need the same A instance to operate on, it's better to keep A's reference saved inside B.
If methodInB is acting as a utility then it should be put in a utility class with static modifier taking A and B type parameters.
Check below:
public class A { }
public class B { }
public class MyUtility {
public static void methodInB(A a, B b) {
//operate on a and b
}
}
// MyUtility can also have a dependency on A and B both and thus make methodInB a non static methodInB
public class MyUtilityBean {
private A a;
private B b;
public void methodInB() {
//operate on a and b
}
}
//Other wise A acts as a dependency of B
public class B {
private A a;
public void methodInB() {
//operate on a
}
}
Related
I'm trying to create these two enum classes
import static B.B1;
public enum A {
A1(B1);
private A(B b) {
System.out.println(b);
}
}
import static A.A1;
public enum B {
B1(A1);
private B(A a) {
System.out.println(a);
}
}
but when i run this code
public class Main {
public static void main(String[] args) {
A1.ordinal();
}
}
i get the following output
null
B1
instead of
A1
B1
how can I solve this problem?
You can't solve this inside the constructors. It's a fundamental limitation of the way classes are initialized: if a class cyclically refers to itself during initialization, it sees the current state of the class, which may mean that final fields can be observed to be null, even though you can see them as non-null later.
Instead, you can have a method on the enums to get the "other":
public enum A {
A1;
B other() { return B.B1; }
}
public enum B {
B1;
A other() { return A.A1; }
}
Now, A1.other() will give you B1; and B1.other() will give you A1.
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.
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 );
}
};
So I have this abstract class
public abstract class A {
protected final boolean b;
protected A (boolean b){
this.b = b;
}
}
And this class that extends A
public class C extends A{
protected C() {
super(false);
}
}
I dont want "b" to be able to change its' value once it's initialized
But I dont know how to do it without the compiler going haywire.
Any suggestions are welcome. Thanks in advance.
EDIT1: static removed from b.
EDIT 2: Ok realised the problem and fixed see above.
Special thanks to J.Lucky :)
I'd suggest you make use of the final keyword.
Try the following codes:
abstract class A {
final protected boolean b;
A(boolean b) {
this.b = b;
}
//No setter method
//public abstract void setB(boolean b);
public abstract boolean getB();
}
class C extends A {
C(boolean b) {
super(b);
}
#Override
public boolean getB() {
return b;
}
}
Sample implementation would be:
public static void main(String args[]) {
C c = new C(true);
System.out.println(c.getB());
}
Since b now is a final variable, you will be forced to initialize it on your constructor and you will not have any way of changing b anymore. Even if you provide a setter method for b, the compiler will stop you.
EDIT 2:
Say you created another class called 'D' and this time you know you want to set it to false by default. You can have something like:
class D extends A {
D() {
super(false);
}
//You can also overload it so that you will have a choice
D(boolean b) {
super(b);
}
#Override
public boolean getB() {
return b;
}
public static void main(String[] args) {
D defaultBVal = D();
D customBVal = D(true);
System.out.println(defaultBVal.getB()); //false
System.out.println(customBVal.getB()); //true
}
}
Solution: You should change the boolean into a Boolean, make it private, provide a getter and a protected setter. In the setter you should check whether the Boolean has been initialized. If so, you should either ignore resetting, or throw and Exception
well how about this:
public abstract class A {
private static Boolean b;
//setB is declared here and, depending on the class that implements it,
//it initializes the value of the variable "b"
protected abstract void setB();
}
public class C extends A{
protected void setB() {
if(b != null) b = true;
}
}
Now the variable is only initialized once when its called. There are still some problems. Someone could use reflection to change the value. Also, when the object is serialized is possible that someone could change the value. If you have a multiple threads accessing this then you should synchronize the method. However, if these aren't issues then this solution might work for you.
So, one friend sent me this code and said that it had compiled successfully and returned 42.
But, the bothering thing is the method in parent class that "returns" 42 is private, and the method that is called on is in child class, and it's public. So, can anybody tell why and how this works?
static class A {
private int f() {
return 42;
}
}
static class B extends A {
public int f2() {
return super.f();
}
}
public static void main(String[] args) {
System.out.print(new B().f2());
}
It returns 42.
I tried to get rid of static, and
class A {
private int f() {
return 42;
}
}
class B extends A {
public int f2() {
return super.f();
}
}
public static void main(String[] args) {
Main m= new Main();
B b= m.new B();
System.out.print(b.f2());
}
it still returns 42.
Since both of the classes (A and B) are nested in Main, they can access the private int f() method.
If you extract the sources of A and B in top-level classes, this won't happen and you'll fail to compile.
The point of private is that "outside" classes should not be able to see private variables. But A and B are both part of the same class, or are nested within each other, so they can access each others private members.
So this will work:
public class A {
private void a() {
int bVal = this.new B().val; //! Accessing B private
}
class B {
A a = new A();
private int val = 10;
public void b() {
a.a(); // !! Accessing A private
}
}
BUT, this will fail, even if both A and B are in the same file but not within each other:
class A {
private void a() {}
}
class B extends A {
A a = new A();
public void b() {
a.a(); // can't see even if B extends A
}
}
This is because both classes A and B are nested inside another class, i.e both classes are inner classes of (or "part of") another same class. Since they (Data Members and Methods) are basically a member of the outer class,they are accessible within other inner classes even if private.
Java allows us Nesting of classes,If You Don't know about nested classes first read this :
http://docs.oracle.com/javase/tutorial/java/javaOO/nested.html
class Outer{
class A {
private int f() {
return 42;
}//Method f() is a private member of A and accessible by Outer
}
class B extends A {
public int f2() {
return super.f();
}//As class B is inner class of Outer it can access members of outer,thus indirectly member of A
}
public static void main(String[] args) {
System.out.print(new B().f2());
}
}