简体   繁体   English

是否可以像Java一样从子类引用嵌套类?

[英]Is it possible to reference a nested class from a subclass like in Java?

There is a Java library I'm interacting with that has the following: 我正在与之交互的Java库具有以下内容:

class Superclass {
    static class Nested {}
}

class Subclass extends Superclass {}

This is code is illegal in Kotlin: 这是Kotlin的代码是非法的:

class Test() {
    val thing1 = Superclass.Nested()
    val thing2 = Subclass.Nested()
}

The compiler says that Subclass.Nested is an unresolved reference. 编译器说Subclass.Nested是一个未解析的引用。 However, the equivalent Java code is not illegal: 但是,等效的Java代码不是非法的:

class Test {
    Superclass.Nested thing1 = new Superclass.Nested();
    Subclass.Nested thing2 = new Subclass.Nested();
}

Is there some other way in Kotlin to reference a nested class by qualifying it with a subclass instead of the superclass? 在Kotlin中是否有其他方法通过使用子类而不是超类来限定它来引用嵌套类?

(Why? Because there is an unusual deprecation pattern in play here: Superclass is deprecated and is being replaced by Subclass . The Nested class is going to be moved into Subclass later. That is the external constraint I am working under.) (为什么?因为这里有一个不寻常的弃用模式: Superclass已被弃用并被Subclass取代。 Nested类将在稍后移入Subclass 。这是我正在使用的外部约束。)

I am not sure if this solves your problem, buy you can access the Nested class from the Subclass, so you could do something like this: 我不确定这是否解决了你的问题,买你可以从Subclass访问Nested类,所以你可以这样做:

open class Superclass {
    class Nested
}

class Subclass : Superclass() {

    companion object Nested {
        operator fun invoke(): Superclass.Nested = Nested()
    }

}

class Test() {
    val thing1 = Superclass.Nested()
    val thing2 = Subclass.Nested()
}

Also, to avoid any confunsion you could just make a function that creates the Nested class 此外,为了避免任何混淆,您可以创建一个创建Nested类的函数

class Subclass : Superclass() {

    companion object {
        fun createNested() = Nested()
    }

}

As you can't access the source code or have to wait for the PR to be approved, I probably would try it with typealias instead, eg: 由于您无法访问源代码或必须等待PR被批准,我可能会尝试使用typealias ,例如:

typealias MyNested = Superclass.Nested

and use it like: 并使用它像:

MyNested()

As soon as Superclass is obsolete you only need to replace the type-alias, eg: 一旦Superclass过时,您只需要替换类型别名,例如:

typealias MyNested = Subclass.Nested

That way you only have 1 place where you need to adapt your code when Superclass is removed. 这样,在删除Superclass时,您只需要一个需要调整代码的位置。

It's now really a pity that both classes aren't under your control and that this feature of Java doesn't work in Kotlin. 现在真的很遗憾,这两个类都不在你的控制之下,并且Java的这个特性在Kotlin中不起作用。 On the other hand I am really glad that it isn't. 另一方面,我很高兴事实并非如此。 Something like Subclass.Nested when there actually isn't any such nested class there, isn't really convenient in my opinion. Subclass.Nested这样的东西,实际上没有任何这样的嵌套类,在我看来并不是很方便。 However, that's also what is possible with extension functions... so now I am in conflict ;-) 然而,这也是扩展功能的可能性......所以现在我处于冲突中;-)

As also said in the comment: there might be a chance that this could also just be a bug. 正如评论中所说的那样:这可能只是一个错误。 I didn't find any sources yet whether this was a deliberate design decision or not. 我还没有找到任何消息来源,这是否是一个故意的设计决定。 It sounds good to me, but that doesn't mean it was intentional. 这对我来说听起来不错,但这并不意味着它是故意的。 You may want to ask the same question in the Kotlin forums or open an issue and link it here. 您可能想在Kotlin论坛中提出相同的问题或者打开一个问题并在此链接。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM