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!
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() ...
}
}
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.
Related
A simple example:
I got three methods [A & B & C], and their relationship is easy. In A method it calls B; in B method it calls C. So if I draw on paper it looks like:
A
B
C
I would like to make the "code" itself can clearly reveal this relationship so that as we read the code we can understand "how they call each other" in a big picture. Rather than we keep doing "find usage" or something else.
I know it's a little bit hard since we sometimes can not force [B only be accessible by A] and [C only accessible by B]. ( Although we can actually make it by inner class, but if there're only three methods it's a little bit pain for creating three classes. )
The way I now try to achieve this is to make the "method name" somehow reveals their relationship. But it is not a really realistic way to do it.
Apart from how can this be implemented in Java, does any other programming language have this kind of feature? I would also really like to know how does the mechanism implemented.
Many thanks for any advice or response.
It seems to me that you should realize the reason why you want to split this the code on three methods.
If you can create these three methods A, B, C in one single class and make B and C methods private, so this makes you sure that nothing will call B and C outside your class.
But if your goal is to make some restrictions inside the class, so maybe it's better to keep A, B, C as a single method, because in Java you can't restrict methods in such way.
Is possible to create such kind of relationship only passing B as parameter to A and C as parameter to C.
This can be accomplished with lambda expressions since Java 8 or with anonym classes prior java 8.
Other systems are not possible because you can't be sure that other methods can't call it.
Functional languages handle that very well. Here is an example using javascript:
var a = function(fn) {
// Do something
fn();
}
var b = function(fn) {
// Do something
fn();
}
var c = function() {
// Do something
}
// To call it
a(b(c));
Note that this solution define the relationship between a, b and c at execution time of the code a(b(c))
In java this is more difficult to do (prior of lambda expressions):
public interface Command {
public void execute();
}
public class X {
public void a(Command comm) {
// Do something
comm.execute();
}
public void b(Command comm) {
// Do something
comm.execute();
}
public void c() {
// Do something
}
}
final X x = new X();
x.a(new Command() {
public void execute() {
x.b(new Command() {
public void execute() {
x.c();
}
});
}
});
say, I have the following code (it's a quiz question, so I can run it in my IDE but the logic how it's working is not quite clear to me):
public class Test {
public static void main(String[] args){
A aInstance1 = new A();
A aInstance2 = new B();
A aInstance3 = new C();
aInstance1.doSth();
aInstance2.doSth();
aInstance3.doSth();
}
}
class A {
public static void doSth(){
System.out.println("Doing something in A");
}
}
class B extends A {
public static void doSth(){
System.out.println("Doing something in B");
}
}
class C extends B {
public static void doSth(){
System.out.println("Doing something in C");
}
}
The output will be the following:
Doing something in A
Doing something in A
Doing something in A
Thus, my first question is: what is the meaning of the declaration like
A aInstance2 = new B();
i.e., why to create an object of class B declaring it as an instance of class A? How the properties of aInstance2 as an object of class B change compared to the declaration
B aInstance2 = new B();
?
If I remove the word static from the declaration of the methods doSth() in the classes A, B, and C, the output changes to
Doing something in A
Doing something in B
Doing something in C
Thus, when the methods were static, the method doSth() of class A didn't get overridden by those of the subclasses and the output was always "Doing something in A" produced by the objects of different classes, whereas when it became an instance (non-static) method, it gets overridden (if I'm using the right term here). Why is it so?
Removing the word static you are doing Dynamic Binding , because you are pretty much saying : "Even though i know this object is of type A i want it to behave like a B ".
Adding the word static means you are making that method part of the class[Reference type] ,and each time you are calling :"A dosmth()" he knows it only applies to A so it shows the result of the mothod from the class A.
As to what would you do this?I for one learned about this feature from school and studied it even more when i decided to go to interviews becuase it;s one of the things that the interviewer wants to see if you can handle.
If you don't mind I will post a link with information about Static and Dynamic Binding
http://javarevisited.blogspot.ro/2012/03/what-is-static-and-dynamic-binding-in.html
Because static method is based on Reference type .
aInstance1.doSth();
aInstance2.doSth();
aInstance3.doSth();
So internally it converts into :
A.doSth();
A.doSth();
A.doSth();
Static methods are class methods while non-static ones are instance methods. Therefore, when you call a static method over an instance you are actually calling it over the declared type of this instance. So, all below calls actually performs the same call: A.doSth() since all instances are declared as type A.
aInstance1.doSth();
aInstance2.doSth();
aInstance3.doSth();
When you remove the static keyword, doSth() method becomes an instance method. Instance methods are performed over objects instead of classes. Moreover, when you re-declare an instance method in a subclass, this method is overriden by the subclass. In your example, class B and C override doSth(). Thus, each class provides its own implementation.
Overriding depends on having an instance of a class. A static method is not associated with any instance of a class so the concept is not applicable.
Making static methods works faster, because there's no need to wait until run-time to figure out which method to call.
Overriding in Java simply means that the particular method would be called based on the run time type of the object and not on the compile time type of it.
Illustration -
When doSth() is static:
A aInstance1 = new A();
A aInstance2 = new B();
A aInstance3 = new C();
aInstance1.doSth();
aInstance2.doSth();
aInstance3.doSth();
In the above code, the compiler will decide at compile time that without instance it should be called for A. No overriding.
When doSth() is not static:
A aInstance1 = new A();
A aInstance2 = new B();
A aInstance3 = new C();
aInstance1.doSth();
aInstance2.doSth();
aInstance3.doSth();
In the above code, the compiler will decide at run time that the method is not static and should be overridden by there respective instances.
static methods are at class level and act on the reference type(LHS of ==) unlike instance level methods which are dynamically dispatched based on the instance type(RHS of ==)
I was asked this question in an interview . I have a base class (say class A) and then two subclasses B and C. Now I have no control over the constructor of B and C(those constructors can't be private , has to be public ) but the requirement is that every instance of B and Cshould be a singleton . How can I achieve this ?
I think I'd do this in the constructor for A. Get it to call this.getClass(), and use that to do a lookup in private HashSet. If you get a hit, then an instance of the class has previously been created, and you throw an exception.
public abstract class A {
private static HashSet<Class<?>> classes = new HashSet<Class<?>>();
public A () {
synchronized (classes) {
Class<?> c = this.getClass();
if (classes.contains(c)) {
throw NotSingletonException("Class " + c + " is not singleton");
}
classes.add(c);
}
}
}
If you arrange that all of A's constructors do this, then subclasses cannot avoid the check. And since the JLS won't let you put a try / catch around a this() or super() call, the constructor for the subclass can't ever return normally once that exception has been thrown.
I'd say that this is a pretty hard interview question ...
#emory comments:
What if B and C are not final? Then I could create classes B1, B2, C1, C2, etc.
The problem here (if it counts as a problem) is that the B1 and B2 instances are also B instances, and that means that the B instance is no longer a singleton ... depending on the definition of singleton you are aspiring to implement.
I can see a couple of ways of dealing with this:
You could reflectively test the subclass modifiers see if the classes are final, and refuse to create instances of non-final classes ... just in case.
You could replace the HashSet<Class> with a List<Class>. Then each time the A constructor is called, it would iterate over the list calling elem.isAssignableFrom(c) for each element class. If any call returns true, the (strict) singleton invariant is violated so an exception should be thrown.
The logic may need to be adjusted depending on the model of singleton-ness you are trying to enforce, but the general solution applies: record the classes and examine / compare new classes with previous ones.
I am showing it for the class B
Though you can use Double checked locking, and synchronized on method to do it.. i am showing you a quick and dirty way of doing it...
public class B {
private static B b = new B();
private B() {}
public static B getInstance() {
return b;
}
}
If class a extends class b, and class b extends class c, does a inherit from both c and b? If so, in case of conflict between the 2, is there an error or does one override another (and if so, which one)?
Please rename the question if it is unsuitably titled.
EDIT: what I mean by conflict is something like the following:
class c {
int foo;
//Stuff
}
class b extends c {
String foo;
//Stuff
}
class a extends b {
//Stuff
}
Is a.foo a string or an int?
Another edit: So from what I gather, inheritance here is a bit like CSS - the closer the rule is set, the larger priority it has (e.g. inline styles override stylesheets). Is that a good way of considering this, or is it significantly different?
If something exists in both b and c, a will inherit whichever one b uses.
Yes, a inherits from b and c. I don't see how there can be a conflict in this situation since b's method overrides will be valid for a. You may be thinking of the diamond problem that comes from conflicts from multiple inheritance, but that's when you have two different parents, not two parents with one parent being the parent of the other.
You can run into a "soft" diamond problem with interfaces, where two methods have the same signature, but the rules for one method don't match those of another. Since neither interface has an implementation for their methods, there is no compilation problem (that I know of), just a logical problem.
Edit Ah, I've seen your edit regarding variables, and I agree with Jimpanzee's response to it. It's certainly easy to test:
public class Test3 {
public static void main(String[] args) {
MyA myA = new MyA();
System.out.println("foo := " + myA.foo);
}
}
class MyC {
public int foo = 3;
//Stuff
}
class MyB extends MyC {
public String foo = "foo";
//Stuff
}
class MyA extends MyB {
}
well, the rule is as follows.
Any subclass will inherit nearest up its hierarchy. so a will get everything from b. Because everything which is on inheritance stack will be available till b. as b had inherited already everything from its inheritance hierarchy.
Secondly, if b over-rides anything(instance variable/method), then a will see over-ridden version. So in your case a will get String foo.
This answer has a much better example, and points out that doing this sort of thing is considered bad practice. (Eclipse will give you a warning, for example.) Extending your code a bit:
class c {
int foo = 42;
//Stuff
}
class b extends c {
String foo = "foostr";
//Stuff
}
class a extends b {
//Stuff
}
class Main{
public static void main(String[] args){
a mya = new a();
System.out.println(mya.foo);
}
}
Running java Main prints foostr.
In Java only methods are subject to overriding. Everything else is just inherited and there is only the issue of a namespace clash, but everything is still accessible. In your example both foos are accessible in A (I've corrected the class names to make them conform to the strong Java naming conventions):
class C {
int foo;
//Stuff
}
class B extends C {
String foo;
//Stuff
}
class A extends B {
String x = ((B)this).foo;
int i = ((C)this).foo;
}
Yes, it inherits from both c and b.
In order to prevent/avoid conflicts, Java support a single hierarchy model (differently from other OOP languages like C++ which allow multiple-class inheritance model).
What is the best use of Inheritance, other than it will reduce redundant code!
Let us take an example
Class A:Base Class
Class B:Sub Class
and Class C.
CLASS A
^
| And CLASS C
|
|
CLASS B
i can use methods from Class A, in Class B by inheritance.
in the same i can use the methods from Class A, in Class C, by creating instance of Class A.(say A is Public)
using inheritance, only reduce creating new Object/Instance?
Plz help me to better understand!
A great benefit is polymorphism. If classes B and C both inherit from A, then whenever an object of type A is required, it can be replaced by either an object of type B or an object of type C. Assuming the corresponding methods are overriden in B and C, this is very handy to get different behavior depending on which object you pass.
Example:
class A {
public void foo() { System.out.println("A"); }
}
class B extends A {
public void foo() { System.out.println("B"); }
}
class C extends A {
public void foo() { System.out.println("C"); }
}
Then:
public static void printMessage(A obj) {
obj.foo();
}
public static void main(String[] args) {
A b = new B();
printMessage(b); // prints 'B'
A c = new C();
printMessage(c); // prints 'C'
}
The main point of inheritance is polymorphism: to allow other classes to use an instance of ClassB knowing only that it can be used as a ClassA.
My favourite example is streams - I could easily write a copyStream method taking an InputStream and an OutputStream for example, using only the methods declared on those types. Then I could copy a FileInputStream to a ByteArrayOutputStream, or use network-related streams etc, all without changing any of the code in the copyStream method.
The main reason to use inheritance is not to remove redundant code.
Inheritance and all magic made possible is a key, central point in OOP. Extending a class doesn't only allow you to use its functionality, but also modify (by polimorphism) and add more functionality.
The difference comes with the need to understand the ability to pass class B into functions that act on class A. In this sense B is-a type of A where class C has or owns A. The difference is small and only significant in certain circumstance.
That is not to say that the difference is often made explicit in code tbh. Often people will inherit when they really want ownership and sometimes they do ownership when an object really is-a type of something else.