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.
Related
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 :
public interface MyFirstInterface {
void myFirstAbstractMethod();
default void myDefaultMethod() {
System.out.println("Hi I am default method in Interface.");
}
}
Class:
public class MyFirstClass{
public static void main(String[] args) {
MyFirstInterface myFirstInterface = new MyFirstInterface() {
#Override
public void myMethod() {
System.out.println("Main class : "+this.getClass());
}
};
myFirstInterface.myMethod();
myFirstInterface.defaultMethod();
}
}
Now we know we are instantiating a anonymous class, what I want to know is Why would anyone use it? What is the advantage or disadvantage of doing it?
It is not a constructor. It is a method a() declaration with the return type A.
Also, we can instantiate an interface using an anonymous class. Runnable for example:
Runnable r = new Runnable() {
#Override
public void run() { ... }
};
Runnable r = () -> { ... }
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");
}
}
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.
wondering how it is possible to call public m method?
public class Test1 {
public static void main(String[] args) {
Test1 test = new Test1() {
public void m() {
System.out.println("m");
}
};
}
}
I don't believe you can. You'd have to create an interface or subclass. (Well, okay, that's probably not true. You could probably do it with reflection.)
E.g., like this (where you call it via test.m() after construction):
public class Test1 {
public static void main(String[] args) {
SubTest1 test = new SubTest1() {
public void m() {
System.out.println("m");
}
};
test.m();
}
private static abstract class SubTest1 extends Test1 {
public abstract void m();
}
}
Or like this, where it happens during construction:
public class Test1 {
public static void main(String[] args) {
SubTest1 test = new SubTest1() {
public void m() {
System.out.println("m");
}
};
}
private static abstract class SubTest1 extends Test1 {
public SubTest1() {
this.m();
}
public abstract void m();
}
}
You can't define an anonymous class constructor, so that last uses the constructor of the SubTest1 class and the abstract method.
You cannot directly invoke m since test is of type Test1 which does not contain a method called m, but you should never find yourself in a situation like this. The whole point of anonymous classes is to alter some already-existent aspect of the base class's functionality, so adding new methods makes no sense. Consider rethinking your design or using a named class instead.
Of course, if you won't care about test in the future you could do this:
new Test1() {
public void m() {
System.out.println("m");
}
}.m();
Although you would rarely want to do something like this, it could be useful if you're working with Thread or Runnable and need to invoke the run method.
If Test1 had a method called "m" you could just call test.m() after you instantiated the inner class:
public class Test1 {
public static void main(String[] args) {
Test1 test = new Test1() {
public void m() {
System.out.println("New Behavior");
}
};
test.m();
}
public void m() {
System.out.println ("Default Behavior");
}
}
Running this would output:
New Behavior