I have this class:
public class MyThread {
public static void main(String[] args) {
Thread thread = new Thread() {
public void run() {
System.out.print("Test from Anonymous Class!");
}
};
Thread newThread = new Thread(thread);
newThread.run();
}
}
When i run this program, i get Test from Anonymous Class!.
Now, i'm trying to simulate this behavior with another class like this:
interface MyInterface {
public void doTest();
}
class MyClass implements MyInterface {
public MyClass() {}
public MyClass(MyInterface myInterface) {}
public void doTest() {
System.out.println("Test from MyClass!");
}
}
public class Test {
public static void main(String[] args) {
MyClass myClass1 = new MyClass() {
public void doTest() {
System.out.println("Test from Anonymous Class!");
}
};
MyClass myClass2 = new MyClass(myClass1);
myClass2.doTest();
}
}
When i run this program, i get Test from MyClass!. Why is in the fist example printing out Test from Anonymous Class!? How can i get the same behavior with MyClass class?
Thanks in advance!
It seems you want to implement a delegation from a class that takes as parameter of the constructor an interface.
The Thread constructor uses the Runnable instance provided as parameter as target of the execution when you invoke Thread#start() while your custom class doesn't mimic this behavior. You indeed do nothing with the MyInterface parameter passed :
public MyClass(MyInterface myInterface) {}
To implement a delegation, you should add a MyInterface field in MyClass and value it in the constructor.
Then use it in doTest() method.
public MyClass(MyInterface myInterface) {}
private MyInterface myInterface;
...
public MyClass(MyInterface myInterface) {
this.myInterface = myInterface;
}
public void doTest() {
// do some processing
..
// then delegate
myInterface.doTest();
}
}
That's because you're doing Nothing with your param myClass1
public MyClass(MyInterface myInterface) {}
You get the parameter, so what? if you want to do what the parameter do, you must invoke the method:
myClass1.doTest()
>"Test from Anonymous Class!"
What you're doing is rare, but if you invoke the method from the correct object, you will get what you want :)
Another way, rare but valid, is to have an instance variable, and call it:
class MyClass implements MyInterface {
MyClass myOtherClass;
public MyClass() {}
public MyClass(MyInterface myInterface) {
this.myOtherClass = myInterface;
}
public void doTest() {
System.out.println("Test from MyClass!");
}
}
Then, you call the method inside it:
public class Test {
public static void main(String[] args) {
MyClass myClass1 = new MyClass() {
public void doTest() {
System.out.println("Test from Anonymous Class!");
}
};
MyClass myClass2 = new MyClass(myClass1);
myClass2.myOtherClass.doTest(); // calling method from myClass1
}
}
You need to initialize your target ,so it will call the method in your class
class MyClass implements MyInterface {
MyInterface myInterface;
public MyClass() {}
public MyClass(MyInterface myInterface) {
this.myInterface=myInterface;
}
public void doTest() {
if(myInterface !=null){
myInterface.doTest();
return;
}
System.out.println("Test from MyClass!");
}
}
The answer is simple.
The run() method in Thread is overriden and it will always be the one to run.
In the second example myClass2 uses it instance doTest() method and myClass1 is never used, except in constuctor.
Related
If you implement an interface and create an instance, the type of instance variable is USUALLY interface name. Which means
public interface MyIntefrace {
void method();
}
public class MyClass implements MyInterface {
void method() { System.out.println(); }
}
public class MyTest {
public static void main(String[] args) {
// 1) usually the type of instance var is MyInterface
MyInterface instance = new MyClass();
instance.method();
// 2) you can use MyClass for instance var type though
// but usually 1) is preferred in interface case
MyClass instance2 = new MyClass();
}
}
But how about the abstract class? instance variable type can be either abstract class or its subclass.
Wondering which one is preferred, 3) or 4) in code below?
Or is there any rule to use only either of them in abstract class case?
Which means is there a case when I need to use 3) or 4) only?
public abstract class MyAbstract {
abstract void method();
void method2() {
System.out.println();
}
}
public class MyClass extends MyAbstract {
void method() {
System.out.println("abstract method");
}
#Override
void method2() {
System.out.println("method");
}
public static void main(String[] args) {
// 3)
MyAbstract instance = new MyClass();
instance.method();
instance.method2();
// 4)
MyClass instance2 = new MyClass();
instance2.method();
instance2.method2();
}
}
interface Sporty {
public void beSporty();
}
class Ferrari implements Sporty {
public void beSporty() {
System.out.println("inside Ferrari impelemnting Sporty");
}
}
class RacingFlats implements Sporty {
public void beSporty() {
System.out.println("inside RacingFlats impelemnting Sporty");
}
}
public class TestSportythings {
public static void main(String[] args) {
Sporty[] sportyThings = new Sporty[3];
sportyThings[0] = new Ferrari();
sportyThings[1] = new RacingFlats();
}
}
You can call methods from Array instance of the interface by an object of a class which is implemented that method of the interface.
Like the following:
sportyThings[0].beSporty();
And you will get output:
inside Ferrari impelemnting Sporty
But if you call beSporty() by
sportyThings[2].beSporty();
You will get NullPointerException as sportyThings[2] is not initialized (by new).
I have an abstract class, say AbstractClass where I've got a public void method myMethod without an implementation. While I'm testing this class, I've created an anonymous subclass, where I can implement myMethod as I see fit.
In AbstractClass There's another method, say myImplementedMethod which calls myMethod. Is there a trick to what I can put in myMethod in the anonymous subclass, so as to be able to verify that it has been called?
Edit:
I'm using Mockito for mocking, and it is not my place to use another framework.
public abstract class AbstractClass {
public abstract void myMethod();
public void myImplementedMethod() {
myMethod();
}
public class AbstractClassTest {
#Before
public void setUp() {
AbstractClass myClass = new AbstractClass() {
#Override
public void myMethod(){
//What could I put here?
}
}
}
#Test
public void testMyImplementedMethod() {
myClass.myImplementedMethod();
//check that myMethod is called.
}
}
If Mockito's spy works for you, great. However I don't believe it will capture internal method calls. How about the below...
public class AbstractClassTest {
boolean methodCalled = false;
#Before
public void setUp() {
methodCalled = false;
AbstractClass myClass = new AbstractClass() {
#Override
public void myMethod(){
methodCalled = true;
}
}
}
#Test
public void testMyImplementedMethod() {
assertFalse(methodCalled);
myClass.myImplementedMethod();
assertTrue(methodCalled);
}
}
You could create a spy object on your descendant class, call the implemented method and later ensure the not implemented one was called with verify
AbstractClass myInstance= Mockito.spy(myClass);
myInstance.myImplementedMethod();
Mockito.verify(myInstance).myMethod();
import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.verify;
public class AbstractClassTest {
private AbstractClass myClass;
#Before
public void setUp() {
AbstractClass instance = new AbstractClass() {
#Override
public void myMethod(){}
}
myClass = spy(instance);
}
#Test
public void testMyImplementedMethod() {
myClass.myImplementedMethod();
verify(myClass).myMethod();
}
}
can't you use the reflection api like this
YourClass.getClass().getMethod("myMethod").invoke(obj,args); // pass the appropriate parameters
and if this throws an exception then you havent implemented the method.
I didnt try this myself , if it works do comment .
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
Having issue in Java,
we can call class methods like
interface samp{
public void printMsg();
}
ClassA implements samp{
public void printMsg()
{
S.o.p("Hi ClassA");
}
}
ClassB implements samp{
public void printMsg()
{
S.o.p("Hi ClassB");
}
}
public MainClass{
public static void main(String args())
{
samp s= new ClassA();
s.printMsg();
samp s= new ClassB();
s.printMsg();
}
}
we can do this, am having different type of class method not similar methods for all classes but I want to implement the future is it possible to do? is any other pattern for this, pls help me to find this.
like
ClassA{
public void fun1(){..}
public void fun2(){..}
}
ClassB{
public void fun3(){..}
public void fun4(){..}
}
want to call these methods using a single refrence, need to asign object to that refrence dynamically is it possible friends?...
Thanks in advance
You cant do that using common interface.You can only call the method which is defined in interface using an interface reference type, even though the object it points to belong to another class have different other methods.
you can call only those class function which are defined in interface because its reference can access only those functions. ex:
interface samp{
public void printMsg();
}
ClassA implements samp{
public void printMsg()
{
S.o.p("Hi ClassA");
}
public void newmthd(){
S.o.p("you can't call me from samp reference.");
}
}
ClassB implements samp{
public void printMsg()
{
S.o.p("Hi ClassB");
}
}
public MainClass{
public static void main(String args())
{
samp s= new ClassA();
s.printMsg();
s.newmthd() //error... s don't have any knowledge of this function.
samp s= new ClassB();
s.printMsg();
}
}
Define all the methods you want your reference to have in an a superclass, but leave the implementations empty. Then, create your subclass and override the necessary methods.
Example:
Class MySuperClass {
public void fun1() {}
public void fun2() {}
public void fun3() {}
public void fun4() {}
}
Class ClassA extends MySuperClass {
public void fun1() { //implementation details }
public void fun2() { //implementation details }
}
Class ClassB extends MySuperClass {
public void fun3() { //implementation details }
public void fun4() { //implementation details }
}
public Class Tester {
public static void main(String[] args) {
MySuperClass class1 = new ClassA();
MySuperClass class2 = new ClassB();
}
}