Java - How to call method class with interface without know class name - java

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.

Related

Anonymous inner class - getClass()

I have written the following code:
public class AnonymousClasses {
public void sayHello(){
}
public interface GreetingModule {
public void sayHello();
}
public static void main(String[] args) {
AnonymousClasses jonny = new AnonymousClasses(){
#Override
public void sayHello() {
System.out.println("Hey");
}
};
AnonymousClasses john = new AnonymousClasses(){
#Override
public void sayHello() {
System.out.println("Hi");
}
};
GreetingModule greeting = new GreetingModule() {
#Override
public void sayHello() {
System.out.println("Hello");
}
};
jonny.sayHello();
john.sayHello();
greeting.sayHello();
System.out.println(jonny.getClass());
System.out.println(john.getClass());
System.out.println(greeting.getClass());
}
The output is of course:
Hey
Hi
Hello
class AnonymousClasses$1
class AnonymousClasses$2
class AnonymousClasses$3
However, when I edit my code as follows:
public class AnonymousClasses {
private final GreetingModule greetingModule;
public AnonymousClasses(GreetingModule greetingModule) {
this.greetingModule = greetingModule;
}
public void saySomething() {
greetingModule.sayHello();
}
public interface GreetingModule {
public void sayHello();
}
public static void main(String[] args) {
AnonymousClasses jonny = new AnonymousClasses(new GreetingModule(){
#Override
public void sayHello() {
System.out.println("Hey");
}
});
AnonymousClasses john = new AnonymousClasses(new GreetingModule(){
#Override
public void sayHello() {
System.out.println("Hi");
}
});
GreetingModule greeting = new GreetingModule() {
#Override
public void sayHello() {
System.out.println("Hello");
}
};
jonny.saySomething();
john.saySomething();
greeting.sayHello();
System.out.println(jonny.getClass());
System.out.println(john.getClass());
System.out.println(greeting.getClass());
}
the output is:
Hey
Hi
Hello
class AnonymousClasses
class AnonymousClasses
class AnonymousClasses$3
Can somebody explain me, why there is no name of the inner class with a dolar in the first two getClass() methods? Is it still an inner class?
You are creating instances of the class on the second sample:
AnonymousClasses jonny = new AnonymousClasses(new GreetingModule(){
#Override
public void sayHello() {
System.out.println("Hey");
}
});
To create a anonymous subclass of it would like:
AnonymousClasses jonny = new AnonymousClasses(new GreetingModule(){
#Override
public void sayHello() {
System.out.println("Hey");
}
}) {
// Overriding anything here is optional
};
$ symbol comes with the class name when there is a new unnamed implementation of the class.
In the first example , you are creating new implementations of AnonymousClasses in each case.
AnonymousClasses jonny = new AnonymousClasses(){
#Override
public void sayHello() {
System.out.println("Hey");
}
};
It's similar to creating an object of a subclass with AnonymousClasses as the parent class. In this case, since there is no name for the subclass, JVM appends $1 to its parent's name to create a unique name.
In the second example , you are just creating new objects of same implementation of AnonymousClasses. It might seem similar, but if you notice carefully, each time you are creating a new implementation of GreetingModule interface which is passed to the constructor of AnonymousClasses.
In both the cases, there is no inner class. In first example, they are just the objects of subclasses of AnonymousClasses and in second case, they are objects of the same AnonymousClasses.

Can not cast class to generics in java

Please help resolve an issue regarding generics. I tried many ways but it's still not working.
Problem is:
public static void main(String[] args) {
Utils.execute(new TestAction(), new TestCallBack());
}
Compiler show error:
The method execute(Action<?>, CallBack<?,Action<?>>) in the type Utils is not applicable for the arguments (ImplementClass.TestAction, ImplementClass.TestCallBack)
My classes is:
Action class:
public abstract class Action<R> {
public R getResult() {
return null;
}
}
TestAction class is:
class TestAction extends Action<String> {
#Override
public String getResult() {
return super.getResult();
}
}
Callback class is:
public interface CallBack<R, A extends Action<R>> {
public void onCall(A action);}
TestCallback class is:
class TestCallBack implements CallBack<String, TestAction> {
#Override
public void onCall(TestAction action) {
}
}
And Utils class is:
public class Utils {
public static void execute(Action<?> action, CallBack<?, Action<?>> callback) {
}
}
Thanks a lot.
The second parameter of the execute method is CallBack<?, Action<?>>, and Action there means the Action class itself, subclass of it is not allowed. What you need there is - ? extends Action<?>, which means either Action or some subclass of it.
Try changing the method signature -
public static void execute(Action<?> action, CallBack<?, ? extends Action<?>> callback) {
Note:
Generics are not co-variant. Take for example a method as follows -
static void method(List<Object> l) {}
And an invocation as follows is not allowed -
method(new ArrayList<String>());
You need to change two things,
TestCallBack should be like this -
public static class TestCallBack implements CallBack<String, Action<String>> {
#Override
public void onCall(Action<String> action) {
}
}
and, Utils should be like this -
public static class Utils {
// You need to ensure the same type, not just try and accept anything.
public static <T> void execute(Action<T> action, CallBack<?, Action<T>> callback) {
}
}
or using inner classes of a class called Question -
public abstract class Action<R> {
public R getResult() {
return null;
}
}
public class TestAction extends Action<String> {
#Override
public String getResult() {
return super.getResult();
}
}
public interface CallBack<R, A extends Action<R>> {
public void onCall(A action);
}
public class TestCallBack implements CallBack<String, TestAction> {
#Override
public void onCall(TestAction action) {
}
}
public class Utils {
public void execute(Action<?> action, CallBack<?, ? extends Action<?>> callback) {
}
}
public static void main(String[] args) {
Question question = new Question();
question.new Utils().execute(question.new TestAction(), question.new TestCallBack());
}

Sad logic on types

Code base is littered with code like this:
BaseRecord record = // some BaseRecord
switch(record.source()) {
case FOO:
return process((FooRecord)record);
case BAR:
return process((BarRecord)record);
case QUUX:
return process((QuuxRecord)record);
.
. // ~25 more cases
.
}
and then
private SomeClass process(BarRecord record) { }
private SomeClass process(FooRecord record) { }
private SomeClass process(QuuxRecord record) { }
It makes me terribly sad. Then, every time a new class is derived from BaseRecord, we have to chase all over our code base updating these case statements and adding new process methods. This kind of logic is repeated everywhere, I think too many to add a method for each and override in the classes. How can I improve this?
First solution: good old polymorphism.
Simply add an abstract process() method to the BaseRecord class, and override it in every subclass. The code will thus become:
BaseRecord record = ...;
record.process();
If you can't add the process() method into the BaseRecord class (and its subclasses), then implement the visitor pattern. It will leave the process method outside of the BaseRecord class, but each time you add a new subclass, you'll be forced to modify the Visitor interface, and all its implementations. The compiler will thus check for you that you haven't forgotten a case somwhere in a switch.
public interface RecordVisitor<T> {
T visitFoo(FooRecord foo);
T visitBar(BarRecord foo);
...
}
public abstract class BaseRecord {
public abstract <T> T accept(RecordVisitor<T> visitor);
}
public class FooRecord extends BaseRecord {
#Override
public <T> T accept(RecordVisitor<T> visitor) {
return visitor.visitFoo(this);
}
}
public class BarRecord extends BaseRecord {
#Override
public <T> T accept(RecordVisitor<T> visitor) {
return visitor.visitBar(this);
}
}
Now you simply have to implement RecordVisitor for each block of logic described in the question:
RecordVisitor<Void> visitor = new ProcessRecordVisitor();
record.accept(visitor);
Both Visitor Pattern and Strategy pattern can be put in use here. http://en.wikipedia.org/wiki/Strategy_pattern and http://en.wikipedia.org/wiki/Visitor_pattern
I think this is instructive:
package classplay;
public class ClassPlay
{
public void say(String msg) { System.out.println(msg); }
public static void main(String[] args)
{
ClassPlay cp = new ClassPlay();
cp.go();
}
public void go()
{
A someClass = new C();
say("calling process with double dispatch");
someClass.dueProcess(this);
say("now calling process directly");
process(someClass);
}
public void process(A a)
{
say("processing A");
a.id();
}
public void process(B b)
{
say("processing B");
b.id();
}
public void process(C c)
{
say("processing C");
c.id();
}
abstract class A
{
abstract public void id(); // { System.out.println("Class A"); }
public void dueProcess(ClassPlay cp) { cp.process(this); }
}
class B extends A
{
public void id() { System.out.println("Class B"); }
public void dueProcess(ClassPlay cp) { cp.process(this); }
}
class C extends A
{
public void id() { System.out.println("class C"); }
public void dueProcess(ClassPlay cp) { cp.process(this); }
}
}

calling overridden function in superclass from subclass in JAVA

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();
}
}

Calling a method of a class using an argument of a method which is an object of that class

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);
}
}

Categories

Resources