While working on a project, I ran into a problem I have not ran into before (I am quite new at Java).
Basically this is the problem:
I have two classes in my project, ClassA
and ClassB
. Inside of my main
I create an instance of both classes. The problem comes when I want to write a method for ClassB
that does something with the instance of ClassA
that I created. I don't know if this is possible at all, or how to get around it.
ClassA:
class ClassA {
///...
public static void main(String[] args){
ClassA a = new ClassA();
ClassB b = new ClassB();
}
}
ClassB:
class ClassB() {
///...
public void doSomething(){
//do something with the instance of classA
}
}
CodePudding user response:
It should look like this
public class B() {
public void doSomething(ClassA classA) {
classA.someNonStaticMethodFromClassA()
}
}
CodePudding user response:
There are several possibilities you can use, depending on your concrete problem and architecture:
Instance passing on construction
When creating an instance of ClassB
, you can hand over the ClassA
instance, like this:
class ClassB() {
private ClassA classA;
public ClassB(ClassA classA) {
this.classA = classA;
}
///...
public void doSomething() {
classA.doSomething();
//do something with the instance of classA
}
}
Your main
method should then look like this:
class ClassA {
///...
public static void main(String[] args){
ClassA a = new ClassA();
ClassB b = new ClassB(a); //<-- Here the constructor passing takes place
}
}
Doing it this way, ClassB
will allow for a ClassA
instance to be given when being constructed. (If you don't want this to happen every time, you could add an additional constructor without parameters.)
Instance passing via setter
Very similarly, you can also add a setter to ClassB:
class ClassB() {
private ClassA classA;
public void setClassA(ClassA classA) {
this.classA = classA; //<-- here the local instance variable is populated
}
///...
public void doSomething() {
classA.doSomething();
//do something with the instance of classA
}
}
Your main
method should then look like this:
class ClassA {
///...
public static void main(String[] args){
ClassA a = new ClassA();
ClassB b = new ClassB();
b.setClassA(a);
}
}
In this case, you need to make sure, that setClassA
is called before your ClassB
instance tries to doSomething
with the ClassA
instance. (Anyway, you should always check whether classA
is null
before trying to operate on it.)
Instance passing on function call
(Update: I forgot this one when posting my original answer. Abras comment is very helpful too!)
You can change your doSomething()
method to accept a ClassA
instance as parameter:
class ClassB() {
///...
public void doSomething(Class a){
a.doSomething(); // <-- use the passed-in ClassA instance
//do something with the instance of classA
}
}
You would then have to adapt your call to doSomething
of the ClassB
instance and supply a ClassA
instance.
Subclassing
If you make ClassB
a subclass of ClassA
, they can "share" their variables. It would then look like this:
class ClassA {
private ClassA a;
///...
public static void main(String[] args){
ClassA a = new ClassA();
ClassB b = new ClassB();
}
class ClassB {
public void doSomething() {
a.doSomething(); //<-- here, the "a" variable of the "outer" class is used
//do something with the instance of classA
}
}
}
In this case, there's no need to explicitly hand over the ClassA
instance to ClassB
. Anyway, you should use subclasses only in limited contexts, e. g. if it is not used anywhere else in your application.
Other possibilities
Other possibilities include more advanced design patterns like Singletons, Services, and so on. This would probably go beyond the scope of this answer.
One last remark
In your example, ClassA
is containing the main
method and also creating an instance of itself and dealing with it. Nevertheless this is possible, it seems a to be code smell to me. You could think about migrating your main
method to a separate class.
CodePudding user response:
What do you intend to do with the instance of ClassA
?
Say you want to modify a ClassA
public variable from ClassB
, here's an example
ClassA:
class ClassA {
public int someVariable = 10;
///...
public static void main(String[] args){
ClassA a = new ClassA();
ClassB b = new ClassB();
b.doSomething(a);
}
}
ClassB:
class ClassB {
///...
public void doSomething(ClassA a){
a.someVariable = 5;
}
}
That's the most basic way of doing it, but an OOP programmer would almost never do it like that.
Here's another example: Say that, for some reason, you want someVariable
to be modified only when the new value is greater than 12
ClassA:
class ClassA {
private int someVariable = 10;
public void setSomeVariable(int newValue) {
if(newValue > 12) {
someVariable = newValue;
}
}
///...
public static void main(String[] args){
ClassA a = new ClassA();
ClassB b = new ClassB();
b.doSomething(a);
}
}
ClassB:
class ClassB {
///...
public void doSomething(ClassA a){
a.setSomeVariable(15);
}
}
In this example, the setSomeVariable
method is called a setter, because it sets a private variable that would otherwise be inaccessible from ClassB
.
Usually you use setters when you want to perform checks on the new value (like we did) or when you want to do some operations once the variable is set. There are also getters methods, see for yourself when to use them.
p.s. : if you don't know what public
and private
stand for, or when and why to use them, I suggest you google that as well.