Ok, maybe I´m asking a total nonsense here, but here is the deal.
I have two java clases A and B that comes from different libraries, that looks somethink like
public class A {
method1()
}
public class B {
method1()
method2()
}
Later, I want something like
if (condition)
temp = new A()
else
temp = new B()
so later I´ll be able to use
temp.method1()
without thinking if its A or B
I guess that if A and B inherits from a parent C, this would be easy, but that´s not the case neither I can change it...
So... is there a elegant way to solve this?
I´m mapping both objects into a third one, but I find it cumbersome. So... any ideas?
I would consider making wrapper interfaces & classes around the base classes.
For example make interface Method1 { method1(); } and then make:
class AMethod1 implements Method1 {
A a;
method1() { a.method1(); }
}
with appropriate constructors & what not.
You can try extending both of these class and then you can have full control over them, and then make them implement single interface
You can either try answer provided by #Jigar Joshi or instead of extrending those classes you can write wrappers for them that would implement the same interface.
Check Adapter pattern. This allows you to make incompatible interfaces compatible.
With the Adapter pattern you do not exterd the classes. Instead, you write a new class implementing your interface and forwarding (delegating) the call to the real object.
You can use reflection.
public static void invokeMethod1(Object o) throws Exception {
o.getClass().getDeclaredMethod("method1").invoke(o);
}
public class Wrapper {
public Wrapper(A a)
{ this.a = a }
public Wrapper(B b)
{ this.b = b }
public void method1()
{
if(a == null)
b.method1();
else
a.method1();
}
}
A bit brute force, but it would work.
Related
Sorry, i can't give better title.I have two class A and B.A class is singleton class.it always gives same object to whoever want it.Here B class always want that A object refenence. check follow code
class B
{
private A a;
B(){
this.a=A.getAObject();
}
public void process(String[] args)
{
a.sendData();//line 1
(or)
A.getAObject().sendData();//line 2
}
}
which is best way as mentioned above line 1 or line 2 as performance wise like that??
You can reference of one class to another class by making reference of the other class
In your code you do something like this :
class B {
private A a;
B(A a){
this.a=a; //refernce of a
}
public void display(){
a.getA(); //display method of a
}
}
class A{
public void getA(){
....
}
}
In many cases the differences will be insignificant.
But there would be scenarios like where you have to create a lot of instances of B. So in those scenarios there would be a performance impact since introducing a filed to that class means taking more memory when creating a instance.
If it is not a scenario like that, I think its better to assign it to a variable, since it will improve the readability of the code if you use that instance often in the class.
Okay, the title is a little bit cryptic, an example will show better what I mean, suppose the following structure:
interface I {
methodCall();
}
class A implements I {
}
class B implements I {
}
class C implements I {
}
class Main {
private A a;
private B b;
private C c;
//other interesting stuff
void doSomeMainMethod() {
a.methodCall();
b.methodCall();
c.methodCall();
}
}
This code has been heavily simplified, the classes A, B and C implement methodCall() obviously, but there is no need to explicitely show that in the code.
What I want to ask is the following:
Is there a way to tell Java to generate my doSomeMainMethod method? I want to tell Java to call methodCall() on all objects of type I in class Main.
Preferably without the use of reflection, because with reflection I think it is possible or if reflection is needed, is there a way to wrap it up such that it at least looks non-hackish? Ofcourse it needs to be safe (as safe as possible) aswell.
class Main {
private A a;
private B b;
private C c;
private I[] instances = new I[]{a, b, c};
//other interesting stuff
void doSomeMainMethod() {
for(I instance : instances) {
instance.methodCall();
}
}
If you want the method to be generated then you can use ASM generation or (probably simpler option) implement your own AnnotationProcessor. With the second option you should annotate your classes and then scan for this annotation in compile time and generate decired method.
interface I {
void methodCall();
List<I> INSTANCES = new ArrayList<I>();
}
Now, in every constructor of classes that implements interface I, do this:
I.INSTANCES.add(this);
In main:
for (I i : I.INSTANCES) {
// do something with every instance of I
}
EDIT:
This will add all instances of I. To limit it to the objects created in Main, let´s add a parameter, createdBy. It is not quite elegant, but it is just Java, no Reflection ...
public A(Class createdBy) {
if (createdBy.equals(Main.class) {
I.INSTANCES.add(this);
}
}
Consider:
public class test01{
public void doSomething(){
// do something
}
}
public class test02{
public void printSomething(){
// print something
}
}
// in main
test01 t1 = new test01();
test02 t2 = new test02();
// I want do to something like this
test01 t3 = t1.merge(t2);
// with t3 I should be able to access both t1 and t2 functions
t3.doSomething();
t3.printSomething();
Please let me know if this is possible in Java? If yes, then let me know how can I achieve this?
There is no multiple inheritance in java. What you can do is making test02 a subclass of test01 then create test03 as a subclass of test02.
OR
you can compose them into a Test03 class like this:
public class Test03 {
private Test01 test01;
private Test02 test02;
public void doSomething() {
test01.doSomething();
}
public void printSomething() {
test02.printSomething();
}
}
Please note that in java you shouldn't use class names like test01. They should be meaningful and comform to the java class naming guidelines.
Your best option is probably this:
public class TestSet {
private test01 t1 = new test01();
private test02 t2 = new test02();
public void doSomething() {
t1.doSomething();
}
public void printSomething() {
t2.printSomething();
}
}
In some languages, multiple inheritance is supported, which may be what you're looking for here. But not in Java. You may or may not want to make a couple of interfaces here to tie TestSet more closely together with test01 and test02.
Please let me know if this is possible in Java?
It is not possible. You cannot combine behaviour dynamically like that in Java.
The normal way to combine behaviour in Java is to use some combination of inheritance and wrappering or delegation. Even then, there will be an issue of subtyping ... unless you use interfaces ... because Java does not allow a class to have multiple (direct) superclasses.
Consider for #Panzercrisis's example. While his test03 class implements methods with the same signatures as the test01 and test02 classes, an instance of test03 is not type compatible with either of them. (You can't use a test03 instance as a test01 or a test02. Java doesn't support duck typing!)
To address that you would need to define interfaces face01 and face02 that are implemented by test01 and test02 respectively. Then you would implement test03 as implementing both face01 and face02.
But this is all static classes and static typing.
Under some circumstances, you could use DynamicProxy or something similar to "synthesize" a class that "merges" the behaviour of two existing classes. However, that is all done with static types and code generation behind the scenes. Moreover, this approach would only viable if you'd had the foresight to define a bunch of interfaces (e.g. face01 and face02) and write your application code against the interfaces rather than the implementation classes.
You can define a class Y in another class X as inner class and you can use class Y in class X. Other than that, as I know there is no way to do that.
Short answer, no it's not possible how you describe.
The appearance of doing this might be possible if test01 and test02 where interfaces and you had a third class test03 implement both. In C++ this would be done by multiple inheritance but that would function much the same way (i.e. you would have to create a third class that instead extends both) and this option isn't available in Java anyway.
Another option would be some sort of composition such as #Panzercrisis describes.
The final option (I can think of) would be to have test02 extend test01 but that alters test02.
But generally, no, not possible.
No you can't, really do this in way how you describe this,
you can do
public class test01 extend test02{ ....
}
so your test1, you can use methods from both classes,
but if you can really whant yo play with merging classes together, you can do some abomination like this one:
public class MyObject {
Map<String, Object> objects = new HashMap<String, Object>();
Map<String, Method> methods = new HashMap<String, Method>();
public Object execute(String methodAName)
{
Object object = objects.get(methodAName);
Method method = methods.get(methodAName);
if (object==null || method==null)
{
throw new RuntimeException("method not found");
}
try {
return method.invoke(object, null);
} catch (Exception e) {
throw new RuntimeException(e);
}
}
public void merge(Object o) {
for (Method m : o.getClass().getMethods()) {
objects.put(m.getName(), o);
methods.put(m.getName(), m);
}
}
}
and when you can use it like that
MyObject o = new MyObject();
o.merge(new test01());
o.merge(new test02());
o.execute("printSomething");
o.execute("doSomething");
but as i said, not recommended
You can do something similar using Java inheritance, But not the same thing. you can use extends here. But you have to make sure method overriding not happen else your requirement not match.
Test02 extends Test01
Then
Test03 extends Test02
Now you can achieve some thing similar.
Test03 test=new Test03();
test.callMethodInTest1();
test.callMethodInTest2();
Sample:
public class Test1 {
public String callMethodInTest1() {
return "test1";
}
}
.
public class Test2 extends Test1{
public String callMethodInTest2() {
return "test2";
}
}
.
public class Test03 extends Test2 {
public static void main(String[] args){
Test03 sample=new Test03();
sample.callMethodInTest1();
sample.callMethodInTest2();
}
}
Take a look at this code (from here)
abstract class EntityA {
AssocA myA;
abstract void meet();
}
abstract class AssocA {
int something;
abstract void greet();
}
class AssocAConcrete extends AssocA {
void greet() {
System.out.println("hello");
}
void salute() {
System.out.println("I am saluting.")
}
}
class EntityAConcrete extends EntityA {
void meet() {
System.out.println("I am about to meet someone");
((AssocAConcrete)myA).salute();
}
}
There are two parallel inheritance trees, for a parent class and an associated class. The problem is with line 23:
((AssocAConcrete)myA).salute();
It is a pain and I have that kind of thing all over my code. Even though that line is part of the concrete implementation of Entity, I need to remind it that I want to use the concrete implementation of AssocA, AssocAConcrete.
Is there some kind of annotation to declare that relationship? Or is there a better, more colloquial Java way to express this design? Thanks!
This is in response to #Dave, because I want to put some code in...
Interesting! So the invocation would look something like this:
AssocAConcrete myAssoc = new Assoca();
EnitityA<T extends AssocA> myEntity = new EntityA<AssocAConcrete>();
myEntity.setAssoc(myAssoc);
myAssoc.salute();
Yes? That's really cool. I think I will use it!
I would think this is a lot neater using generics...
abstract class EntityA<T extends AssocA> {
// Basically, this means myA is at least an AssocA but possibly more...
T myA;
abstract void meet();
}
abstract class AssocA {
int something;
abstract void greet();
}
class AssocAConcrete extends AssocA {
void greet() {
System.out.println("hello");
}
void salute() {
System.out.println("I am saluting.");
}
}
class EntityAConcrete extends EntityA<AssocAConcrete> {
void meet() {
System.out.println("I am about to meet someone");
myA.salute();
}
}
Aside from avoiding the casting, this also makes it much easier to add different functionality in your AssocA implementations. There should always be a way to do things without using dummy implementations (ie methods that just throw "NotImplementedException") or casting. Even though it isn't always easy or worth the refactoring time to do so. In other words, no one is going to blame you for casting (well...maybe some people will but you can't please everyone).
EDIT (Notes on instantiation):
From #pitosalas' comments below...
//Won't work...can't call 'new' on abstract class AssocA
AssocAConcrete myAssoc = new Assoca();
//Instead, do this...
AssocAConcrete myAssoc = new AssocAConcrete();
And then....
// Again, won't work. T is only declaring the type inside your class/method.
// When using it to declare a variable, you have to say EXACTLY what you're making,
// or at least something as exact as the methods you're trying to invoke
EnitityA<T extends AssocA> myEntity = new EntityA<AssocAConcrete>();
//Instead do this...
EnitityA<AssocAConcrete> myEntity = new EntityAConcrete();
// Or this...
EntityAConcrete myEntity = new EntityAConcrete();
And then this should be good...
// Assuming this is defined as `public void setAssoc(T newAssoc) {this.myA = newAssoc;}`
myEntity.setAssoc(myAssoc);
myAssoc.salute();
Looks suspicious to me. There is nothing terrible about casting, but in this case, you could resolve the issue by bringing the salute method into AssocA. Subclasses of AssocA can provide their implementations; that's part of the benefit of inheritance.
What you are doing now is saying all EntityA instances have an AssocA instance, but then in your meet method you basically force the AssocA instance to be an AssocAConcrete instance. That's the part that is suspicious; why does AssocA exist if you really need an AssocAConcrete.
Another option (based on your comments) is to invoke salute in the greet method. That way, the specific subclass has specified behavior greet, defined in the superclass, and does what it wants. In this case, salute could become private or protected. Another implementation can easily do something different, like runLikeHell.
The problem of parallel class hierarchies is very real and really sucks. The logical coupling that AssocAConcrete always go with EntityAConcrete can not be expressed with the type system.
You can not specialize the type of myA in EntityAConcrete to be AssocAConcrete, without hiding it from a superclass. I think the closest work that addressed that was "Family polymorphism", but that's not mainstream.
If you have a large part of code where you are using the reference "myA" you could declare another reference like that:
public AssocAConcrete myAConcrete = (AssocAConcrete)myA;
now you can use the new reference myAConcrete and access the functions of the AssocAConcrete Class.
If you need to do this a lot like hvgotcodes mentioned you should probbably consider moving the method up to the AssocA Class.
I have two classes (A and B) which depend on each other in following sense:
Each class has a method performing some action.
The action of each class depends on an action of the other class.
So, if the user calls action of class A, it should automatically call
action of class B.
Same for the other way. But an infinite loop should be prevented.
I have found some code, which deals with this issue, but it seems to be a
little dumb to me: Infinite loop is prevented by locking.
import java.util.concurrent.locks.*;
import static java.lang.System.*;
import org.junit.*;
public class TEST_DependentActions {
static class A {
private B b = null;
private final ReentrantLock actionOnBLock = new ReentrantLock();
public void setB(B b) {
this.b = b;
}
public void actionOnB() {
if (!actionOnBLock.isLocked()) {
actionOnBLock.lock();
b.actionOnA();
actionOnBLock.unlock();
}
}
}
static class B {
private A a = null;
private final ReentrantLock actionOnALock = new ReentrantLock();
public void setA(A a) {
this.a = a;
}
public void actionOnA() {
if (!actionOnALock.isLocked()) {
actionOnALock.lock();
a.actionOnB();
actionOnALock.unlock();
}
}
}
#Test
public void test1()
throws Exception {
out.println("acting on class A first:");
A a = new A(); B b = new B();
a.setB(b); b.setA(a);
a.actionOnB();
}
#Test
public void test2()
throws Exception {
out.println("acting on class B first:");
A a = new A(); B b = new B();
a.setB(b); b.setA(a);
b.actionOnA();
}
}
Output is as following:
acting on class A first:
A : calling class B's action.
B : calling class A's action.
acting on class B first:
B : calling class A's action.
A : calling class B's action.
Well, it works, but doesn't seem to be an optimal solution.
How would you do it?
Is there a pattern which deal with such issue?
EDIT:
I want to know it in general.
But let's say I have a Container which contains multiple Elements.
The Container provides the method remove(someElement) and the
Element also provides a method removeMe().
Both methods depend on each other, but can't be connected to one
method, because both methods additionally perform some internal stuff, which is only
accessible inside each class.
I would handle this by rethinking the logic. Circular dependencies are typically a sign that something is a little ... off. Without more insight into the exact problem I can't be more specific.
Can you make one of the methods private/internal.
This should ensure only the other one can be called by client code, and you always know which way the calls work.
Alternatively, using your container/element example, something like this:
public class Container
{
public void Remove(Element e)
{
e.RemoveImplementation();
RemoveImplementation();
}
// Not directly callable by client code, but callable
// from Element class in the same package
protected void RemoveImplementation()
{
// Mess with internals of this class here
}
}
public class Element
{
private Container container;
public void Remove()
{
RemoveImplementation();
container.RemoveImplementation();
}
// Not directly callable by client code, but callable
// from Container class in the same package
protected void RemoveImplementation()
{
// Mess with internals of this class here.
}
}
I'm not sure if there is a common name for this pattern.
My recommendation would be to think less about the code and more about the design. Can the shared operations be abstracted into a new class which both classes can communicate with? Has the functionality been incorrectly shared across 2 classes?
At Uni this year they introduce the concept of "code smells", which is a bunch of "gut reactions" that code needs re-factoring. Perhaps could help?
For an overview try:
Wikipedia Code Smells or this book.
Perhaps you could tell us more about what you are trying to represent in the code?
I hope this helps.
The solution presented looks perfectly acceptable for the given scenario. But it really depends on what the actions mean whether this behaviour is correct or not. If this is exactly the behaviour that you want, then I'm not sure you have a problem.
Addendum:
In which case I'd say, split out the 'extra stuff' into a separate method, so that remove on the container can call the 'extra stuff' on the element without the recursive call back. Similarly, the extra stuff on the container can be separated so that removeMe can call a method on the container that only does the non-recursive stuff.
i think this could be solved by a boolean value global to the class (make it an instance variable of course). it checks if([the boolean variable]) and if it is true; it runs the call to the other method, if it is false it doesn't. just inside the if statement set the check equal to false. then at the end of each method make it set to true.
thats just how i would do it though.
If an exception is raised your implementation will not get unlocked. Locks can be expensive, a slight more light weight approach is to use an AtomicBoolean
private final AtomicBoolean actionOnBLock = new AtomicBoolean();
public void actionOnB() {
if (!actionOnBLock.getAndSet(true))
try {
b.actionOnA();
} finally {
actionOnBLock.set(false);
}
}
As others have suggested, a better way would be to write the code so one down not have to call the other. Instead you could have a method which calls A and B so the two objects don't need to know about each other.
public class AB {
private final A a;
private final B b;
public AB(A a, B b) {
this.a = a;
this.b = b;
}
public void action() {
a.action(); // doesn't call b.
b.action(); // doesn't call a.
}
}
As others have said, I think in most situations you should try to avoid this and refactor your code so the problem does not occur. But then there a certainly situations where this might not be an option or totally unavoidable. The most general approach to this is to ensure that before method A calls method B (and vice versa), it has to ensure the object of A is in state where an additional call to A immediately returns and thus results in a no-op. This is really very abstract and can be quite hard to apply to a concrete class and implementation.
Taking your example of container and element classes (say, C and E), where the C has a method C.remove(E e) and E has a method E.remove(), you could implement it like this:
class C:
elements = [...] // List of elements
remove(e):
if not elements.contains(e):
return
elements.remove(e)
// Do necessary internal stuff here...
// and finally call remove on e
e.remove()
class E:
container = ... // The current container of E
remove():
if container is none:
return
c = container
container = none
// Do necessary internal stuff here...
// and finally call remove on c
c.remove(this)
function fooA() calling fooB() and fooB() again calling fooA() is a valid recursion.
Recursion does not always have to be same function calling itself.
So, how do we prevent a recursive function from infinitely looping ?
By having a terminating condition right ?
I guess thats the way to go. However, I agree with other's comments on rethinking the design and avoid such recursions.
Simon's solution below also relies on the terminating conditions like
if not elements.contains(e):
return
and
if container is none:
return