Actually, you can. Non out of box, but it is possible ;)
Let's consider this example.
First, create a class MyParent
in Java
public class MyParent {
}
And, define extension method in this interface:
interface MyParentExt {
fun String.ext(importantParam: Int)
}
So, let MyParent
implement this interface.
public class MyParent implements MyParentExt {
@NonNull
@Override
public String ext(@NonNull String $receiver, int importantParam) {
return $receiver;
}
public String ext(int importantParam) {
return "Kotlin > Java";
}
}
So, let's check what we can do in childs:
public class MyJavaChild extends MyParent {
MyJavaChild() {
"Java xD".ext(0);
ext("Java xD", 0);
ext(0);
}
}
class MyGreatKotlinChild : MyParent() {
init {
"Kotlin is cool".ext(0)
ext("Kotlin is cool", 0)
ext(0)
}
}
So, we can access our extension method in both, Java and Kotlin using lang-specified notation.
As one of your requirements you wanted this method to be protected.
Unfortunately, visibility of interface methods is always public. So, you still should be able to call this function on a member.
But... Let's check how does it actually works ;)
public class Test {
public static void main(String[] args) {
MyChild child = new MyChild();
child.ext("Java...", 0);
child.ext(0);
}
}
fun main() {
child.ext(0)
child.ext("It actually works...", 0)
"String".ext(0)
}
Also, your parent class just can extend ParentOfMyParent
class where you would define your extension methods:
abstract class ParentOfMyParent {
protected abstract fun String.ext()
}
public class Parent extends ParentOfMyParent {
@Override
protected void ext(@NotNull String $receiver) {
}
}
class Child : Parent() {
init {
"".ext()
}
}
public class ChildJava extends Parent {
ChildJava() {
ext("");
}
}
This way method has a wantned visibility.