views:

98

answers:

4

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!

+1  A: 

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.

Bill K
I'm sure you meant "class B's constructor". Overriding Thread.start() won't do a lot of good.
ChssPly76
+1  A: 

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.

dfa
A: 

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.

theoverture
+1  A: 

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() ... 
 }
}
Steve B.
Great, thanks! A lot of great advice throughout, but being limited in time, this was the easiest fix for something poorly designed and too complicated.
Monster