Java extension/abstraction/implementation question
-
22-07-2019 - |
Question
I have three classes (class A, class B, and class C).
Class A calls an instance of B and runs start().
Class B extends Thread, so when start() is called, anything in the run() method is executed.
In the run() thread, there is an instance of class C.
Is there anyway to allow a method in Class C to call a method in Class A, without instantiating a new instance of Class A?
Since I can't extend class A to class B (because "Thread" is already extended), I don't know how I'd go about doing this.
Sorry for being vague, but my project features far too much code and is way too complicated to provide a direct code example.
Thanks!
Solution
So you have
class A {
void run()
{
new B().start();
}
}
class B extends Thread {
public void run(){
C c = new C();
c.do something with A .. }
}
You can pass the caller, which might get ugly, as you have to pass A all the way down to C through B:
class A {
void run()
{
new B(this).start();
}
}
class B extends Thread {
public void run(A a){
C c = new C();
c.do something(a)..
}
}
or simplify, especially if B and C have no other reason for being:
class A {
public void run()
{
this.do something() ...
}
}
OTHER TIPS
this is a circular dependency, a very bad thing in OOP in my (modest) opinion.
You must refactor your code to provide a common class for A and C.
The best way might be for class B's start to be overloaded to take a parameter (A, or better yet, an interface implemented by A). Then B can either store that for retrieval by C (if it's an inner class) or pass it to C's constructor...
EDIT:
Although as the commenter mentioned overriding the constructor would work, it doesn't fit the parameters of the question which was phrased in such a way that B already existed, so my suggestion is to overload the start() like this:
b.start(A aParam) {
a=aParam;
start();
}
This version is NOT thread safe however. B's constructor works if B is actually instantiated every time, or if C is instantiated when b starts, then it could be passed to C's constructor as it's instantiated.
By the way, extending thread is not generally as good as implementing runnable for quite a few reasons.
Another way to utilize thread behavior in java is to implement Runnable. Conceivably you could extend A, and implement Runnable, and use:
Thread t = new Thread( b )
t.start();
Seems ugly from a OOP point of view, but it could conceivably make sense under certain circumstances. The other two answers seem a bit more sensible, but figured that this could be considered.