I have this situation: There are a Java class
public class A {
public void overrideMe(B param){
//TODO: override me in Kotlin!
}
protected static class B {
}
}
and a Kotlin class, which inherits from it and has to override method "overrideMe"
class K: A() {
override fun overrideMe(param: B) {
println("Wow!")
}
}
But Kotlin doesn't allow this behaviour.
'public' function exposes its 'protected (in A)' parameter type B
Is there any way how to resolve this one?
P.S. It's not just a synthetic case - I faced this problem when I tried to implement custom Spring AmqpAppender and to override it's postProcessMessageBeforeSend method.
The protected access modifier is accessible within the package. However, it can also accessible outside the package but through inheritance only.
In Kotlin, all classes are final by default. To permit the derived class to inherit from the base class, we must use the open keyword in front of the base class. Kotlin Inheriting property and methods from base class: When we inherit a class then all the properties and functions are also inherited.
Kotlin does not support multiple inheritance.
protected means access to the method is restricted to the same package or by inheritance. So the answer is, yes, protected methods can be overridden by a subclass in any package. By contrast, package (default) scoped methods are not visible even to subclasses that are in a different package.
There is no way to resolve this in Kotlin, and here is why:
The difference is that protected
actually means something subtly different in Kotlin than in Java.
protected
in Kotlin means:
kotlin protected: same as private (visible inside the file containing the declaration) + visible in subclasses too;
protected
in Java means:
java protected: the member can only be accessed within its own package (as with package-private) and, in addition, by a subclass of its class in another package.
And with this knowledge the issue should be clear, the protected static class B
in Kotlin is more like private static class B
in Java. Therefore the warning is correct.
The Kotlin-Java Interop guide specifically states:
protected
remainsprotected
(note that Java allows accessing protected members from other classes in the same package and Kotlin doesn't, so Java classes will have broader access to the code);
Conclusion:
This means that Kotlin interprets the Java-protected
as if it was a Kotlin-protected
ergo there is no way to implement the class K
in Kotlin as it is. The least you must do to make it work is create C extends A
(in Java) that handles all public access of B
and then extend this class in Kotlin. Like in this issue Calling protected static methods
The culprit:
The main problem is Javas behaviour of static nested classes, which
interacts with the instance members of its outer class (and other classes) just like any other top-level class. In effect, a static nested class is behaviorally a top-level class that has been nested in another top-level class for packaging convenience.
This convenient behaviour creates the problem in the first place.
Side note:
Probably the better match for Java-protected
is Kotlins internal
which provides a better level of encapsulation.
kotlin internal: any client inside this module who sees the declaring class sees its internal members;
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With