将类中使用的接口的列表传递给构造函数

时间:2019-06-13 07:46:42

标签: kotlin

我有两个具有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}")
        }
    }
}

2 个答案:

答案 0 :(得分:2)

扩展@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
    }
}

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

答案 1 :(得分:1)

如果我正确理解了您的问题,则您的代码只需进行一点改进即可解决您的问题

interface A {
    var name: String
}

interface B {
    var job: String
}

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

class D {
    fun getList(): E<C> = E(
        arrayListOf(
            C("user1", "job1"),
            C("user2", "job2"),
            C("user3", "job3")
        )
    )
}

class E<T>(val list: List<T>) where T : A, T: B {
    fun display() {
        // for (i in 1..10) will throw OutOfBoundsException
        list.forEach {
            println("my name is ${it.name} and I am a ${it.job}")
        }
    }
}

// to test
fun main(args: Array<String>) {
    D().getList().display()

    /* will prints
       my name is user1 and I am a job1
       my name is user2 and I am a job2
       my name is user3 and I am a job3 */
}