How can I call the most specific method using generics? - java

Having the following example:
public class Test {
public static class A {}
public static void main(String[] args) {
A a = new A();
m1(a);
}
public static <T> void m1(T t) {
// t.getClass().getSimpleName() is A
// t instanceof A is true
m2(t);
}
/* Not called */
public static void m2(A a) {
System.out.println("A");
}
public static void m2(Object o) {
// o.getClass().getSimpleName() is A
// o instanceof A is true
System.out.println("O");
}
}
I don't understand why m2(Object o) is chosen instead of m2(A a). As you can see, when m2(t) is called, t "is an A".
Output:
actual
O
expected
A
How can I use generics for the situation above so that m2(A a) is chosen?
Edit:
I'd like to have a general solution that will work even if I add a type B (similar to A).
...
public static void main(String[] args) {
A a = new A();
m1(a);
B b = new B();
m1(b);
}
...
public static void m2(B b) {
System.out.println("B");
}
...
Output:
actual
O
O
expected
A
B

You have to do:
public static <T extends A> void m1(T t) {
m2(t);
}
Otherwise the compiler cannot infer that the passed parameter is compliant with m2(A a) and with pick m2(Object o) instead.

You are looking for double dispatch which Java does not support. I do not think that generics can help here, but there's the visitor design pattern with which you can emulate it:
public class Test {
public static interface Visitable {
void accept(Visitor visitor);
}
public static class A implements Visitable {
#Override
public void accept(Visitor visitor) {
visitor.visit(this);
}
}
public static class B implements Visitable {
#Override
public void accept(Visitor visitor) {
visitor.visit(this);
}
}
public static interface Visitor {
void visit(A a);
void visit(B b);
}
public static class PrintingVisitor implements Visitor {
#Override
public void visit(A a) {
System.out.println("A");
}
#Override
public void visit(B b) {
System.out.println("B");
}
}
public static void main(String[] args) {
Visitable visitable = new A();
m(visitable);
visitable = new B();
m(visitable);
}
public static void m(Visitable visitable) {
visitable.accept(new PrintingVisitor());
}
}

Related

how to call implementation class methods in run method without hardcoding

interface Myinterface
{
boolean run();
}
class MyClass implements Myintr
{
boolean run()
{
boolean status=false;
disp();//hard coded
show();//hard coded
here above two methods are hard coded how can we call without hard coding
}
public void disp()
{
System.out.println("Hello Person");
}
public void show()
{
System.out.println("Welcome");
}
}
class Mainclass
{
public static void main(String args[])
{
Class aClass=Class.forName("Myclass");
Object obj=aClass.newInstance();
Myinterface myinter=(Myinterface)obj.run();
}
}
Your question is extremely unclear, but I suspect you're looking for something like this:
MyInterface.java:
interface MyInterface {
void run();
}
Impl1.java:
class Impl1 implements MyInterface {
#Override
public void run() {
System.out.println("Hello Person");
}
}
Impl2.java:
class Impl2 implements MyInterface {
#Override
public void run() {
System.out.println("Welcome");
}
}
MainClass.java:
class MainClass {
public static void main(String args[]) throws ClassNotFoundException, InstantiationException, IllegalAccessException {
Class<?> aClass = Class.forName("com.mypackage.Impl1");
Object obj = aClass.newInstance();
MyInterface myinter = (MyInterface)obj;
myinter.run();
}
}

In Java is it possible to check at runtime on which subclass a method was called?

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

Java extends generic prototype

I have few classes that implements some interface. Now I want to create new class, which can extend one of them, based on runtime calculation while using interfaces methods. Let's talk in code:
public interface Interface {
public void doSomething();
}
public class A implements Interface {
#Override
public void doSomething() {
System.out.println("hello");
}
}
public class B implements Interface {
#Override
public void doSomething() {
System.out.println("hi");
}
}
These are existing classes, so now I need to do something like this (which is not working of course):
public class C<T extends Interface> extends T {
public void doSomethingElse() {
this.doSomething();
}
public static void main(String[] args) {
C c;
if(isSomethingLoaded) {
c = new C<A>();
} else {
c = new C<B>();
}
c.doSomethingElse();
}
}
Is it possible somehow, except the way that I pass argument Interface other to C's constructor and store to class property..?
A class cannot extend from its type parameter.
Use composition instead of inheritance:
public class C<T extends Interface> {
private final T foo;
public C(T foo){
this.foo = foo;
}
public void doSomethingElse() {
foo.doSomething();
}
public static void main(String[] args) {
C<?> c;
if(isSomethingLoaded) {
c = new C<>(new A());
} else {
c = new C<>(new B());
}
c.doSomethingElse();
}
}
You might even not need the type parameter here, but just use the interface type as argument/ member type.
I think it's situations like this which show why we have the rule of favouring composition over inheritance. Consider this solution using composition:
public class Test {
public interface Interface {
void doSomething();
}
public static class A implements Interface {
#Override
public void doSomething() {
System.out.println("Doing A");
}
}
public static class B implements Interface {
#Override
public void doSomething() {
System.out.println("Doing B");
}
}
public static class C implements Interface {
private Interface composedWith;
public C(Interface i) {
this.composedWith = i;
}
#Override
public void doSomething() {
this.composedWith.doSomething();
}
}
public static void main(String[] args) {
C c;
if(isSomethingLoaded) {
c = new C(new A());
} else {
c = new C(new B());
}
c.doSomething();
}
}
Personally, I feel this is a clearer and move flexible way of achieving what you are trying to do.

How to call parent method of multiple nested inner class

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.

How to dynamically override superclass functions using generics

If you have a base class that is in a jar file that looks like:
public class A {
public void awesome(int i){
}
}
...which is extended by these classes (also in a jar) as follows:
public class A1 extends A {
#Override
public void awesome(int i){
}
}
and
public class A2 extends A {
#Override
public void awesome(int i){
}
}
...is it possible to override the base function in a generic way?
Say there is an implementation that was being added via anonymous inner class - can you code that such that the entire anonymous inner implementation only appears once?
So instead of:
public class Test {
public static void main(String args[]){
A1 mySpecialA1 = new A1(){
#Override
public void awesome(int i){
//awesome implementation
}
};
A2 mySpecialA2 = new A2(){
#Override
public void awesome(int i){
//awesome implementation
}
};
}
}
...you could have (this is where it breaks down):
public class SpecialAFactory {
public static <T extends A> getSpecialA(){
return new T(){
#Override
public void awesome(int i){
//only once
}
};
}
}
So ultimately you would be passing in the subclass that you want to get a new anonymous instance of.
Although you cannot do it with generics, there is a simple, easy to understand, solution that lets you avoid code duplication in cases like that:
public class Test {
public static void main(String args[]){
A1 mySpecialA1 = new A1(){
#Override
public void awesome(int i){
awesomeImplementation(i);
}
};
A2 mySpecialA2 = new A2(){
#Override
public void awesome(int i){
awesomeImplementation(i);
}
};
}
private static void awesomeImplementation(int i) {
//awesome implementation
}
}

Categories