I want to call A.f() from B.f(), but both are inner classes, if I write the traditional way, it does not compiles.
Any easy way without a temporary variable like the A _this in the code?
class MyClass {
[...]
class A {
public void f(){System.out.println("A.f");};
public void g(){System.out.println("A.g");};
}
class B {
public void f(){System.out.println("B.f");};
}
public A a() {
return new A() {
public void g() {
// I want to avoid this step
final A _this = this;
new B() {
public void f() {
System.out.println("foo");
// this works
_this.f();
// but this does not compile
A.this.f();
}
}.f();
}
};
}
[...]
}
You need to surround the code in brackets properly and then A.this.f() compiles fine E.g.
class A {
public void f() {
System.out.println("A.f");
}
public void g() {
System.out.println("A.g");
}
public A a() {
return new A() {
public void g() {
=
new B() {
public void f() {
System.out.println("foo");
A.this.f();
}
}.f();
}
};
}
public static void main(String[] args) {
new A().a().g();
}
}
class B {
public void f() {
System.out.println("B.f");
}
}
Updated : You can replace _this.f(); with new MyClass().new A().f(); but it will result in creation of new Object.
Related
I'm trying to use interfaces in my android java project. Callback interfaces seems to be the answer to C# delegates, but I can't get my head around it, I've read other similar questions, but again, I can't get it to fit my needs or get it to work. What I need is to call a function in Class A that is pass as a parameter to Class B. When class B finishes a task, returns the result to A by calling the function previously saved in a variable:
class A {
B myBClass;
public A() {
myBClass = new B();
myBClass.doSomething(ResultFunction);
//Continue doing other tasks
}
public void ResultFunction(<result parameters>) {
//do something with the result from the task in myBClass
}
}
class B {
Function myCallback;
public B() {
}
public void doSomething(ResultFunction) {
myCallback = callback;
//does something
SomethingFinished();
}
private void SomethingFinished() {
myCallback.call(<result of doSomething>);
}
}
There are 2 ways to do it:
1) Use anonymous class:
Remove ResultFunction argument from doSomething method in class B
And reimplement it in class A
public A() {
myBClass = new B() {
#Override
public void doSomething() {
super.doSomething();
//do here what you need what you want to do in B class
}
}
myBClass.doSomething();
//Continue doing other tasks
}
2) UseCallable interface
interface Callable {
public void call();
}
pass it instead of ResultFunction
class A {
B myBClass;
Callable callable = new Callable {
#Override
public void call() {
//do here what you need what you want to do in B class
}
}
public A() {
myBClass = new B();
myBClass.doSomething(callable);
//Continue doing other tasks
}
}
class B {
Callable myCallback;
public B() {
}
public void doSomething(Callable callable) {
myCallback = callable;
//does something
SomethingFinished();
}
private void SomethingFinished() {
myCallback.call();
}
}
With lambdas it can look like a bit better
public A() {
myBClass = new B();
myBClass.doSomething(()->{
//do here what you need what you want to do in B class
});
//Continue doing other tasks
}
I do not understand why can't you just do the following:
public class A {
private B myBClass;
public A() {
myBClass = new B();
Result result = myBClass.doSomething();
resultFunction(result)
//Continue doing other tasks
}
public void resultFunction(Result result) {
//do something with the result from the task in myBClass
}
}
public class B {
public B() {
}
public Result doSomething() {
//does something
}
}
If, for whatever reason, you must do that, you can do it easily in Java 8 like this:
public class A {
B myBClass;
public A() {
myBClass = new B();
myBClass.doSomething(A::resultFunction);
//Continue doing other tasks
}
public void resultFunction(Result result) {
//do something with the result from the task in myBClass
}
}
public class B {
private Consumer<Result> myCallback;
public B() {
}
public void doSomething(Consumer<Result> callback) {
myCallback = callback;
//does something
myCallback.accept(result);
}
}
When I search for the method by reflection it shows the newly provided method. But I don't know how to invoke that method, if someone has got any idea how to do it please tell me.
//some pakage
pakage xyz;
class A {
// a simple method of class A
public void aMethod() {
//simple print statement
System.out.println("A class method");
}
}
class B {
// a method of class B that takes A types as an argument
public void bMethod(A arg) {
Class c = Class.forName("xyz.A");
Method[] methods = c.getDeclaredMethods();
for (Method method : methods) {
System.out.println(method.getName());
}
}
}
class Test {
public static void main(String[] args) {
B bObj = new B();
bObj.bMethod(new A() {
public void anotherMethod() {
System.out.println("another method");
}
});
}
}
I suppose maybe this is what you want.
package xyz;
import java.lang.reflect.Method;
class A {
// a simple method of class A
public void aMethod() {
//simple print statement
System.out.println("A class method");
}
}
class B {
// a method of class B that takes A types as an argument
public void bMethod(A arg) throws Exception {
Class c = Class.forName(arg.getClass().getName());
Method[] methods = c.getDeclaredMethods();
for (Method method : methods) {
System.out.println(method.getName());
method.invoke(arg);
}
}
}
class Test {
public static void main(String[] args) throws Exception {
B bObj = new B();
bObj.bMethod(new A() {
public void anotherMethod() {
System.out.println("another method");
}
});
}
}
You can use reflection to invoke the method on particular object:
public void invokeSomeMethodOnA(A arg, String methodName) {
Method method = arg.getClass().getDeclaredMethod(methodName);
//To invoke the method:
method.invoke(arg, parameters here);
}
interface Y {
void search(String name);
}
class A implements Y {
void search(String name) {
//Is it possible to say: "If I was called from class B then do a search("B");
}
}
class B extends A {
}
public class Main {
public static void main(String[] args) {
B b = new B();
b.search();
}
}
Given the above code is it possible to reason in superclass which subclass was used for calling a method?
The reason I want to do this is because the code in Search is very similar for all Subclasses, the only thing that changes is the Classname, so I thought there is no need to Override in each subclass. I have updated the code to reflect this. Please let me know if there is a better way of doing it/
Calling this.getClass() inside your search method will give you the concrete class of the current instance.
For example:
class Example
{
static class A {
public void search() {
System.out.println(getClass());
}
}
static class B extends A {}
public static void main (String[] args) throws java.lang.Exception
{
new A().search();
new B().search();
}
}
outputs
class Example$A
class Example$B
The cleanest way to do it is to override the method in each subclass.
interface Y {
void search();
}
class A implements Y {
public void search(){
search("A");
}
protected void search(String name) {
// implement your searching algoithm here
}
}
class B extends A {
public void search(){
search("B");
}
}
public class Main {
public static void main(String[] args) {
B b = new B();
b.search();
}
}
That's the way inheritance is suppose to works. A super class should not know its subclasses.
And, in case you extends your class B, you can easily either:
-Keep the same behaviour as B:
class C extends B {
// do nothing, when calling search, it calls the method implemented in B
}
-Change the behaviour to search for "C"
class C extends B {
public void search(){
search("C"); // or search("whateveryouwant")
}
}
You can simply override the method in class B.
The other way could be to write the search() method as
void search() {
if (this.getClass().equals(B.class)) {
//The logic for B
} else if (this.getClass().equals(A.class)) {
//The logic for A
}
}
You have to provide the fully qualified name for the class.
Better follow template pattern.
interface Y {
void search(String name);
}
abstract class AbstractionTemplate implements Y{
#Override
public void search(String name) {
//a lot of code.
System.out.println("common stuff start");
doImplspecificStuffOnly();
System.out.println("common stuff end");
//a lot of code.
}
abstract void doImplspecificStuffOnly();
}
class A extends AbstractionTemplate{
#Override
void doImplspecificStuffOnly() {
System.out.println("a's stuff");
}
}
class B extends A {
#Override
void doImplspecificStuffOnly() {
System.out.println("B's stuff");
}
}
public class Main {
public static void main(String[] args) {
B b = new B();
b.search("hey");
}
}
class aa {
public void bb() {
class cc {
public void dd() {
System.out.println("hello");
}
}
}
}
How to call dd() method in main method?
class Solution {
public static void main(String arg[]) {
/* i want to call dd() here */
}
}
To call an instance method, you need an instance of that method e.g.
class aa {
interface ii {
public void dd();
}
public ii bb() {
// you can only call the method of a public interface or class
// as cc implements ii, this allows you to call the method.
class cc implements ii {
public void dd() {
System.out.println("hello");
}
}
return new cc();
}
}
later
new aa().bb().dd();
class aa {
public void bb() {
}
static class cc {
void dd() {
System.out.println("hello");
}
}
public static void main(String[] args) {
cc c = new aa.cc();
c.dd();
}
}
You inner class should be in class aa not in method of class aa
And cc class should be static
you can call it using calling bb() call from main like,
public static void main(String... s){
new aa().bb()
}
And modify bb()like,
public void bb()
{
class cc{
public void dd()
{
System.out.println("hello");
}
}
new cc().dd();
}
package innerclasstest;
interface Demo {
}
class Bar {
public void call() {
Foo f = new Foo();
f.doStuff(new Demo() {
public void fall() {
System.out.println("In method args...");
}
});
}
}
class Foo {
public void doStuff(Demo demo) {
System.out.println("In stuff");
}
}
public class ClassArg {
public static void main(String[] args) {
Bar b = new Bar();
b.call();
}
}
In the above example how we can call the anonymous class method Fall. in there is any way to call this method.I don't know which approach I should pick to call this method.
The only reason you cannot write
demo.fall();
is that you didn't announce that method in the interface. Change it like:
interface Demo {
void fall();
}
and then it works.
If you want to do different things with an annonymous class you need to assign it to a variable, as the class is not reusable.
Something like:
Demo extendedDemo = new Demo() {
public void fall() {
System.out.println("In method args...");
}
};
you can use it then for your call:
f.doStuff(extendedDemo);
You can call the internal method at declaration if doStuff can be executed after:
Demo extendedDemo = new Demo() {
public void fall() {
System.out.println("In method args...");
}
}.fall();
If you can't call doStuff later you can call the internal method using reflection:
Method m = extendedDemo.getClass().getMethod("fall", new Class[]{});
m.invoke(extendedDemo, new Class[]{});
Anonymous classes can't be referred anywhere other than the place they have been declared. To call the method it has to be declared in the interface first. Here is your complete listing with the interface tweaked a bit to make use of the method:
interface Demo {
public void fall();
}
class Bar {
public void call() {
Foo f = new Foo();
f.doStuff(new Demo() {
public void fall() {
System.out.println("In method args...");
}
});
}
}
class Foo {
public void doStuff(Demo demo) {
System.out.println("In stuff");
demo.fall();
}
}
public class ClassArg {
public static void main(String[] args) {
Bar b = new Bar();
b.call();
}
}
The output will be:
In stuff
In method args...
See http://docs.oracle.com/javase/tutorial/java/javaOO/anonymousclasses.html
In your situation :
public void doStuff(Demo demo) {
System.out.println("In stuff");
}
in this method call demo.fall() if the Demo interface provides the fall() method declaration.