使用 public 方法从 Java class 继承,在 Kotlin 中接受受保护的 class
Inheritance from Java class with a public method accepting a protected class in Kotlin
我遇到这种情况:
有一个Javaclass
public class A {
public void overrideMe(B param){
//TODO: override me in Kotlin!
}
protected static class B {
}
}
和一个 Kotlin class,继承自它并且必须重写方法 "overrideMe"
class K: A() {
override fun overrideMe(param: B) {
println("Wow!")
}
}
但是 Kotlin 不允许这种行为。
'public' function exposes its 'protected (in A)' parameter type B
有什么办法可以解决这个问题吗?
P.S。这不仅仅是一个综合案例 - 我在尝试实现自定义 Spring AmqpAppender 并覆盖它的 postProcessMessageBeforeSend 方法时遇到了这个问题。
在 Kotlin 中无法解决这个问题,原因如下:
区别在于 protected
在 Kotlin 中的实际含义与在 Java 中的含义略有不同。
protected
在 Kotlin 中表示:
kotlin protected: same as private (visible inside the file containing the declaration) + visible in subclasses too;
protected
在 Java 中表示:
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.
有了这些知识,问题应该很清楚了,Kotlin 中的 protected static class B
更像是 Java 中的 private static class B
。因此警告是正确的。
Kotlin-Java Interop 指南明确指出:
protected
remains protected
(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);
结论:
这意味着 Kotlin 将 Java-protected
解释为好像它是 Kotlin-protected
因此没有办法在 Kotlin 中按原样实现 class K
。至少你必须做的是创建 C extends A
(在 Java 中)来处理 B
的所有 public 访问,然后在 Kotlin 中扩展这个 class .喜欢本期Calling protected static methods
罪魁祸首:
主要问题是Javastatic nested classes的行为,
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.
这种便利行为首先造成了问题。
旁注:
可能更适合 Java-protected
的是 Kotlins internal
,它提供了更好的封装级别。
kotlin internal: any client inside this module who sees the declaring class sees its internal members;
嗯,毕竟结论是:纯Kotlin没有办法解决这种情况。
希望不久的将来AmqpAppender.Event变成public
即使 Java 允许这种行为,在 public 方法中使用 no-public 参数对我来说似乎是一个糟糕的设计(对于 Kotlin 的开发者也是如此)。
我遇到这种情况: 有一个Javaclass
public class A {
public void overrideMe(B param){
//TODO: override me in Kotlin!
}
protected static class B {
}
}
和一个 Kotlin class,继承自它并且必须重写方法 "overrideMe"
class K: A() {
override fun overrideMe(param: B) {
println("Wow!")
}
}
但是 Kotlin 不允许这种行为。
'public' function exposes its 'protected (in A)' parameter type B
有什么办法可以解决这个问题吗?
P.S。这不仅仅是一个综合案例 - 我在尝试实现自定义 Spring AmqpAppender 并覆盖它的 postProcessMessageBeforeSend 方法时遇到了这个问题。
在 Kotlin 中无法解决这个问题,原因如下:
区别在于 protected
在 Kotlin 中的实际含义与在 Java 中的含义略有不同。
protected
在 Kotlin 中表示:
kotlin protected: same as private (visible inside the file containing the declaration) + visible in subclasses too;
protected
在 Java 中表示:
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.
有了这些知识,问题应该很清楚了,Kotlin 中的 protected static class B
更像是 Java 中的 private static class B
。因此警告是正确的。
Kotlin-Java Interop 指南明确指出:
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);
结论:
这意味着 Kotlin 将 Java-protected
解释为好像它是 Kotlin-protected
因此没有办法在 Kotlin 中按原样实现 class K
。至少你必须做的是创建 C extends A
(在 Java 中)来处理 B
的所有 public 访问,然后在 Kotlin 中扩展这个 class .喜欢本期Calling protected static methods
罪魁祸首:
主要问题是Javastatic nested classes的行为,
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.
这种便利行为首先造成了问题。
旁注:
可能更适合 Java-protected
的是 Kotlins internal
,它提供了更好的封装级别。
kotlin internal: any client inside this module who sees the declaring class sees its internal members;
嗯,毕竟结论是:纯Kotlin没有办法解决这种情况。
希望不久的将来AmqpAppender.Event变成public
即使 Java 允许这种行为,在 public 方法中使用 no-public 参数对我来说似乎是一个糟糕的设计(对于 Kotlin 的开发者也是如此)。