我试图找到一个更好的方式来说明类MyList
示例的属性list
应该是扩展List<MyItem>
的任何类,所以从下面开始:
class MyItem {
}
abstract class MyList {
abstract val list: List<MyItem>
abstract fun first(): MyItem
}
class MyLinkedList: MyList() {
override val list: List<MyItem> = LinkedList<MyItem>()
override fun first(): MyItem {
return (list as LinkedList<MyItem>).first
}
}
class MyArrayList: MyList() {
override val list: List<MyItem> = ArrayList()
override fun first(): MyItem {
return list[0]
}
}
这是可以的,虽然我真的很讨厌(list as LinkedList<MyItem>)
转换,因为在我的实际用例中,它会使代码不可读或不可维护(因为它比那个简单的例子复杂得多,现在第二次尝试已经更好了:
class MyItem {
}
abstract class MyList<WrappedList: List<MyItem>> {
abstract val list: WrappedList
abstract fun first(): MyItem
}
class MyLinkedList: MyList<LinkedList<MyItem>>() {
override val list = LinkedList<MyItem>()
override fun first(): MyItem {
return list.first
}
}
class MyArrayList: MyList<ArrayList<MyItem>>() {
override val list = ArrayList<MyItem>()
override fun first(): MyItem {
return list[0]
}
}
这是非常好的,但是在我的用例中,在这种方法中,我最终会做:
abstract class MyList<
WrappedList1: List<MyItem1>,
WrappedList2: List<MyItem2>,
...
WrappedListN: List<MyItemN>
> {
abstract val list1: WrappedList1
abstract val list2: WrappedList2
...
abstract val listn: WrappedListN
...
}
虽然它做了我想让它做的事情,但它看起来有点重复和多余,感觉应该有类似于:
abstract class MyList {
abstract val list1: extends List<MyItem1>
abstract val list2: extends List<MyItem2>
...
abstract val listn: extends List<MyItemN>
...
}
也就是在适当的位置创建匿名的“extends”,而不是命名这么多泛型类型。
有没有办法做到这一点?
1条答案
按热度按时间piztneat1#
我试图找到一种更好的方式来说明类MyList示例的属性列表应该是任何扩展List的类
List<MyItem>
类型的属性实际上已经是这个意思了。不需要更多的语法。这就是Liskov的替换原则--你应该能够使用任何符合List<MyItem>
契约的示例作为这个属性的值。这将是好的,虽然我真的很讨厌(名单作为LinkedList)铸造
你不一定要选。答案取决于你想达到的目标。你似乎在问题进行到一半时改变了目标。
如果您“只是”希望能够在类的实现中使用具体的列表类型,则只需使用该具体类型的单独(私有)属性,并使用覆盖的属性将其作为父类型公开:
现在,如果您也不介意将新类型公开到类之外,那么就更简单了,您只需将被覆盖的属性声明为父属性类型的子类型: