Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

use implementation type in interface in java

I want to make an interface that forces each class that implements it to have a certain functionality, for the implemented class' type.

So say I have classes MyClassA, MyClassB, MyClassC, etc. that all need a function on their own type:

in MyClassA:

public class MyClassA implements MyClass {
    MyClassA function(MyClassA x) {
        doSomethingImplementedInMyClassA(x);
    }
}

in MyClassB:

public class MyClassB implements MyClass {
    MyClassB function(MyClassB x) {
        doSomethingImplementedInMyClassB(x);
    }
}

The question is, how to write the interface MyClass to require such function?

public interface MyClass {
    MyClass function(MyClass x);
}

obviously doesn't work, since the returning type is MyClass and not its implementation. How to do this properly in Java?

like image 573
user1111929 Avatar asked Sep 02 '12 02:09

user1111929


2 Answers

You can use generics:

public interface MyClass<V extends MyClass<V>> {
    V function(V x);
}

public class MyClassA implements MyClass<MyClassA> 

This is called the CRTP.


This is not perfect; it would still allow things like

public class MyClassB implements MyClass<MyClassA> 

To do this correctly, you need higher-kinded types [citation needed], which Java does not support.

like image 117
SLaks Avatar answered Oct 20 '22 08:10

SLaks


If the implementation always calls a method on the argument, why not just add that method to the interface?

interface MyClass {
    MyClass doSomething();
}

class MyClassA implements MyClass {
    MyClassA doSomething() {
        //implementation here
    }
}

class MyClassB implements MyClass {
    MyClassB doSomething() {
        //implementation here
    }
}
like image 35
Daniel Avatar answered Oct 20 '22 07:10

Daniel