8

我有这种情况:有一个Java类

public class A {

    public void overrideMe(B param){
        //TODO: override me in Kotlin!
    }

    protected static class B {

    }
}

和一个 Kotlin 类,它继承自它并且必须覆盖方法“overrideMe”

class K: A() {
    override fun overrideMe(param: B) {
        println("Wow!")
    }
}

但是 Kotlin 不允许这种行为。

'public' 函数公开了它的 'protected (in A)' 参数类型 B

有什么办法可以解决这个问题吗?

PS 这不仅仅是一个综合案例 - 当我尝试实现自定义Spring AmqpAppender并覆盖它的 postProcessMessageBeforeSend 方法时,我遇到了这个问题。

4

2 回答 2

2

在 Kotlin中没有办法解决这个问题,原因如下:

不同之处在于,这protected实际上意味着 Kotlin 与 Java 中的细微差别。

protectedKotlin中意味着:

kotlin protected:与私有相同(在包含声明的文件中可见)+ 在子类中也可见;

protectedJava中意味着:

java protected:该成员只能在其自己的包中访问(与 package-private 一样),此外,它的类在另一个包中的子类也可以访问。

有了这些知识,问题就应该很清楚了protected static class B,Kotlin 中的代码更像private static class BJava。因此警告是正确的。

Kotlin -Java 互操作指南特别指出:

protected仍然存在protected(请注意,Java 允许从同一包中的其他类访问受保护的成员,而 Kotlin 不允许,因此Java 类将具有更广泛的代码访问权限);

结论:

这意味着 Kotlin 将 解释Java-protected为好像它是 Kotlinergo 一样protected,因此无法class K在 Kotlin 中按原样实现。要使其工作,您必须做的至少是创建C extends A(在 Java 中)处理所有公共访问,B然后在 Kotlin 中扩展此类。就像在这个问题中调用受保护的静态方法

罪魁祸首:

主要问题是静态嵌套类的 Java 行为,它

就像任何其他顶级类一样,与其外部类(和其他类)的实例成员交互。实际上,静态嵌套类在行为上是一个顶级类,为了包装方便,它已经嵌套在另一个顶级类中

这种方便的行为首先会产生问题。

边注:

可能更适合 Javaprotected的是 Kotlins internal,它提供了更好的封装级别。

kotlin internal:在这个模块中看到声明类的任何客户端都会看到它的内部成员;

于 2018-03-14T20:50:52.563 回答
0

好吧,毕竟结论是:在纯 Kotlin 中没有办法解决这种情况。

我希望 AmqpAppender.Event 将在不久的将来公开。

即使 Java 允许这种行为,在公共方法中使用非公共参数对我来说似乎是一个糟糕的设计(对于 Kotlin 的开发人员也是如此)。

于 2018-03-19T07:21:08.930 回答