首页 > 解决方案 > 将类中使用的接口列表传递给构造函数

问题描述

我有两个具有 2 个不同变量的接口。我创建了一个实现这两个接口的类。现在我想将第一个接口的列表传递给另一个类的构造函数并使用它的属性(来自两个接口)。到目前为止,我成功地拥有了构造函数,但我找不到如何传递参数列表

interface A {
    var name: String
}

interface B {
    var job: String
}

class C(
    override var name: String,
    override var job: String
) : A, B

class D() {
    private fun getList() {
        val list: List<A> = arrayListOf(
            C("user1", "job1"),
            C("user2", "job2"),
            C("user3", "job3")
        )
        // I want to init E() my constructor here 
    }
}

class E<T>(val list: List<T>) where T : A, T: B {
    fun display() {
        list.forEach {
            println("my name is ${list.get(i).name} and I am a ${list.get(i).job}")
        }
    }
}

标签: kotlin

解决方案


扩展了@Scrobot 给出的答案。

简而言之,你不能做你想做的事。当您指定List<A>类型时,您会忽略有关列表中的元素是否实现接口 B 的信息。

如果你能做你想做的事,你可以很容易地通过执行以下操作来破坏你的代码:

class PureA : A {
    override var name: String
}

val list: List<A> = arrayListOf(
    C("user1", "job"),
    PureA("user2")
)

// The following line will not work, and for good reason
// E(list)

如果最后一行有效,您基本上会破坏您的代码。PureA 是 As 列表中的有效元素,但它不是 E。

以下内容更接近您打算做的事情:

// Doesn't work fully
class D<T> where T: A, T: B {
    private fun getList(): E<T> {
        val list: List<T> = arrayListOf<T>(
            C("user1", "job1"),
            C("user2", "job2"),
            C("user3", "job3")
        )

        E(list)
    }
}

我看不到一个完整的方法来完成你要做什么。我假设您希望将来的类也实现 A 和 B。我发现唯一可行的方法是:

interface AB : A, B

class C(
        override var name: String,
        override var job: String
) : AB

class D {
    private fun getList() {
        val list: List<AB> = arrayListOf(
            C("user1", "job1"),
            C("user2", "job2"),
            C("user3", "job3")
        )

        E(list)
        // I want to init E() my constructor here
    }
}

这是一个非常好的解决方案,即使它为您提供了更多接口。但这通常很好:)


推荐阅读