Suppose I have defined a class with interface like this:
public class myClass {
public void test() {
//here I want to trigger `onStartListener`
}
interface OnStartListener {
public void onStart();
}
}
and class B I have defined like this:
public class ClassB implements myClass.OnStartListener {
public void ClassB() {
myClass test1 = new myClass();
myClass.test();
}
#Override
public void onStart() {
System.out.println("start triggered");
}
}
How can I trigger OnStartListener from test method of myClass so ClassB can handle it?
Yes, you need to subscribe your listener and call the method in the class A:
public class ClassB implements myClass.OnStartListener {
public void ClassB() {
myClass test1 = new myClass(this);
//test1.setListener(this);
myClass.test();
}
#Override
public void onStart() {
System.out.println("start triggered");
}
}
and
public class myClass {
OnStartListener myListener;
public myClass(OnStartListener myListener) {
this.myListener = myListener;
}
public void test() {
//here I want to trigger `onStartListener`
myListener.onStart();
}
interface OnStartListener {
public void onStart();
}
}
Have a look at how frameworks like swing handle listeners. Basically you need to "register" the listener instance (ClassB instance) with myClass and call onStart() on it.
ClassB would probably contain a List<OnStartListener> which is used in a loop and onStart() is called on each element. Registering would mean assing the instance of ClassB to that list.
Related
I'm new in java, I want to call method class from implemented Class with interface without know class name "ClassA", which only know Object c and I have 2 file.
File (1) CobaInterface.java
package cobainterface;
public class CobaInterface {
public static void main(String[] args) {
ImplementedClass implementedClass = new ImplementedClass();
ClassA clsA = new ClassA();
implementedClass.myMethodFromClassA(clsA);
}
}
class ClassA{
public Integer getTwo(){
return 2;
}
}
interface MyInterface {
public void myMethod();
//here interface
public void myMethodFromClassA(Object c);
}
File (2) : ImpementedClass.java
package cobainterface;
public class ImplementedClass extends CobaInterface {
public void myMethodFromClassA(Object c) {
//System.out.println(c.getTwo()); <- wrong when call method c.getTwo()
}
}
How about if I want to call method getTwo() from ClassA without know Class Name, which only know Object c from file (2) as describe in code above. Thanks for advance.
You should use generic types so the implementation knows what the object will be,
interface MyInterface<T> {
public void myMethod();
//here interface
public void myMethodFromClassA(T c);
}
The impl becomes,
package cobainterface;
public class ImplementedClass Implements MyInterface<ClassA> {
public void myMethodFromClassA(ClassA c) {
//System.out.println(c.getTwo()); <- wrong when call method c.getTwo()
}
}
All together,
class Scratch {
public static void main(String[] args) {
ImplementedClass implementedClass = new ImplementedClass();
ClassA clsA = new ClassA();
implementedClass.myMethodFromClassA(clsA);
}
}
class ImplementedClass implements MyInterface<ClassA> {
#Override
public void myMethod() {
}
#Override
public void myMethodFromClassA(ClassA c) {
System.out.println(c.getTwo());
}
}
class ClassA {
public Integer getTwo() {
return 2;
}
}
interface MyInterface<T> {
void myMethod();
void myMethodFromClassA(T c);
}
You could also do a cast
System.out.println((MyClass)c.getTwo());
but you will lose all benefit of type saftey.
Here is the best way I could summarise my situation:
Class1 makes new Thread(new Class2)
Is there a way from inside objects 2 code I can access non-static public methods from object 1?
Not sure if I have explained myself enough but I can answer any questions that could help describe it better
Edit: To elaborate Class1 is a multithreaded server and Class2 is the WorkerClass and i want to access Class1.stop() to stop the server from inside the workerClass
There are at least 3 ways to do this:
(1) Use an anonymous inner class:
public class Class1 {
public void foo() {}
public void bar() {
Thread t = new Thread(new Runnable() {
#Override
public void run() {
foo();
}
});
}
}
(2) Use a named inner class:
public class Class1 {
public void foo() {}
public void bar() {
Thread t = new Thread(new MyRunnable());
}
private class MyRunnable implements Runnable {
#Override
public void run() {
foo();
}
}
}
(3) Pass this to the constructor of another top-level class:
public class Class1 {
public void foo() {}
public void bar() {
Thread t = new Thread(new MyRunnable(this));
}
}
class MyRunnable implements Runnable {
private Class1 class1;
public MyRunnable(Class1 class1) {
this.class1 = class1;
}
#Override
public void run() {
class1.foo();
}
}
Suppose I have two classes A and B where A is a superclass of B. Now, I write a function (override), say funct() in both the classes. Then, if I want to call the funct() in A from an object of B, is it possible?
class A {
public void f() {...}
}
class B extends A {
#Override public void f() { super.f(); }
}
Is that what you want?
If instead you want to call A#f() directly on an instance of type B, you must provide a placeholder function for that:
class B extends A {
#Override public void f() { ... }
public void superF() { super.f(); }
}
new B().f(); // calls B#f();
new B().superF(); // calls A#f();
I have trick such as this situation to operate it in an illogical manner using Flag argument in funct() method :D, like this:
class A {
public void funct(boolean callSuper) {
// avoid using callSuper arg here
}
}
class B extends A {
#Override
public void funct(boolean callSuper) {
if (callSuper) {
super.funct(callSuper);
return;//if return type is void
} else {
//do here the functionality if the flag is false
}
}
}
or
class A {
public void funct() {
}
}
class B extends A {
private boolean callSuper = false;
#Override
public void funct() {
if (callSuper) {
super.funct(); // call A.funct() functionality
setCallSuper(false);
} else {
//do here the functionality of B.funct() if the flag is false
}
}
public void setCallSuper(boolean callSuper){
this.callSuper = callSuper;
}
}
Given classes like
class A {
public void funct() {...}
}
class B extends A {
#Override
public void funct() {...}
}
You ask
Then, if I want to call the funct() in A from an object of B, is it
possible?
So let's take
B b = new B();
b.funct();
A a = b;
a.funct();
((A)b).funct();
The above all do the same thing because of polymorphism and late-binding.
The only way to call the superclass' implementation is to get a reference to that member through the super keyword.
class A {
public void funct() {...}
}
class B extends A {
#Override
public void funct() {
super.funct();
}
}
Consider the following classes
Class A{
public void m1(){
System.out.println("test in A.m1()");
}
public void m2(){
//do something a
}
}
Class B{
public void m1(){
//do something b
}
public void m2(){
//do something b
}
}
Class C{
public void m1(){
//do something c
}
public void m2(){
//do something c
}
}
Class T{
public void m3(Object obj1){
obj1.m1();
}
public void m4(Object obj1){
A a=new A();
m3(a);
}
}
So now my question is, is there any way I can send an open object to a method which will detect what type of object it is and call method of that object class. In this example I am hoping to see the output: "test in A.m1()"
You can use Java's Reflection API to query an arbitrary object to see if it has a method named m1 or m2 and then invoke it. But that is pretty ugly.
Is there anything from stopping you using an interface? Example below (where "..." indicates places where you would put your specific implementation):
interface MyMethods {
public void m1();
public void m2();
}
class A implements MyMethods {
public void m1() { ... }
public void m2() { ... }
}
class B implements MyMethods {
...
}
class C implements MyMethods {
...
}
class T {
public void m3(MyMethods obj1) {
obj1.m1();
}
public void m4(Object obj1) {
// Call m3 three times with different object instance types...
A a = new A();
m3(a);
B b = new B();
m3(b);
C c = new C();
m3(c);
}
}
Sometimes, I create a decorator class like this:
class MyInterfaceDecorator implements MyInterface {
private final MyInterface delegate;
... constructor taking a MyInterface instance ...
#Override
public Object someInterfaceMethod(Some argument) {
return delegate.someInterfaceMethod(argument);
}
... etc, more methods here...
}
Can IntelliJ automatically create this class for me?
Update//
I noticed that IntelliJ has a "Generate" option for generating delegate methods. Create a new class:
public class MyDecoratorClass {
private MyInterfaceWithManyMethods myInterface;
}
Then mark myInterface, go to Menu > Code > Delegate Methods, select all methods you want to wrap and that's it.
//End of update
You could try the "Refactoring" -> "Replace inheritance with delegation" refactoring. It should be able to do this, like this. I call this "Code with Alt+Enter"
Go to the interface you want to generate a decorator for.
public interface MyInterfaceWithManyMethods {
void method1();
void method2();
void method3();
}
Press Alt+Enter, select "Implement Interface", give a name to your Decorator like "MyDecorator". This gives you
public class MyDecorator implements MyInterfaceWithManyMethods {
public void method1() {
}
public void method2() {
}
public void method3() {
}
}
In new class, select the class name, then "Refactor" -> "Replace inheritance with delegation", select your interface, tick all method names, press enter. You'll get:
public class MyDecorator {
private final MyObject object = new MyObject();
public void method1() {
object.method1();
}
public void method2() {
object.method2();
}
public void method3() {
object.method3();
}
private class MyObject implements MyInterfaceWithManyMethods {
public void method1() {
}
public void method2() {
}
public void method3() {
}
}
}
Delete the inner class and the object initializer manually. You get:
public class MyDecorator {
public void method1() {
object.method1();
}
public void method2() {
object.method2();
}
public void method3() {
object.method3();
}
}
Press Alt+Enter on the "object" which is now marked red, select "Create field", select MyInterfaceWithManyMethods.
public class MyDecorator {
private MyInterfaceWithManyMethods object;
public void method1() {
object.method1();
}
public void method2() {
object.method2();
}
public void method3() {
object.method3();
}
}
Select the object variable, press Alt+Enter, select "Add constructor Parameter":
public class MyDecorator {
private MyInterfaceWithManyMethods object;
public MyDecorator(MyInterfaceWithManyMethods object) {
this.object = object;
}
public void method1() {
object.method1();
}
public void method2() {
object.method2();
}
public void method3() {
object.method3();
}
}
You see it's all done with a few strokes of Alt+Enter. Reads like a lot of work but it can be done in less than 20 seconds. If you just have like 2 or 3 methods you might be faster with a live template, however if you have many methods with complex signatures you'll get a working result in about 20 seconds with this method. Alt+Enter simply rocks :D
You can perhaps add a file template like:
class ${NAME} implements ${INTERFACE} {
private final ${INTERFACE} delegate;
public ${NAME}(final ${INTERFACE} delegate) {
this.delegate = delegate;
}
and then when you have created the file using this template, just use
Alt+Inser and choice delegate Methods.
It's not perfect, but this could be a shortcut