我有一个适配器:
class PhotoAdapter : RecyclerView.Adapter<PhotoAdapter.AbstractViewHolder>() {
fun addItems(list: ArrayList<AbstractItem>) {
val position = items.size
items.addAll(list)
notifyItemRangeInserted(position, list.size)
}
abstract class AbstractItem(
open val id: Int
)
class PhotoItem(
override val id: Int,
val url: String?
) : AbstractItem(id)
...
}
和使用它的片段:
val adapter = PhotoAdapter()
val list: ArrayList<PhotoAdapter.PhotoItem> = ArrayList(emptyList<PhotoAdapter.PhotoItem>())
adapter.addItems(list)
但是尽管PhotoItem
嵌套在AbstractItem
中,但我无法编译:
如果我将ArrayList
中的addItems()
更改为简单的List
,则会编译:
fun addItems(list: List<AbstractItem>) {
...
也许类型转换也可以,但是我没有检查。
问题是,为什么实现(ArrayList
)和接口(List
)在嵌套类上有不同的观点?
更新
我改写了Java,这会更加清楚。
public class Adapter extends RecyclerView.Adapter<Adapter.AbstractViewHolder> {
private ArrayList<AbstractItem> items;
public void addItems(ArrayList<AbstractItem> list) {
int position = items.size();
items.addAll(list);
notifyItemRangeInserted(position, list.size());
}
abstract class AbstractViewHolder extends RecyclerView.ViewHolder {
public AbstractViewHolder(@NonNull View itemView) {
super(itemView);
}
}
public abstract class AbstractItem {
int id;
}
public class PhotoItem extends AbstractItem {
int id;
String url;
}
}
public class Example {
void init() {
ArrayList<Adapter.PhotoItem> list = new ArrayList<>();
Adapter adapter = new Adapter();
adapter.addItems(list);
}
}
答案 0 :(得分:3)
因为List
是协变的(定义为List<out T>
),所以List<PhotoAdapter.PhotoItem>
是List<AbstractItem>
的子类型。但是MutableList
和ArrayList
是不变的,这意味着ArrayList<PhotoAdapter.PhotoItem>
不是ArrayList<AbstractItem>
的子类型(或超类型)。
有关原因的详细说明,请参见https://kotlinlang.org/docs/reference/generics.html#variance(我认为在这里没有太多重复之处)。
答案 1 :(得分:1)
在Java中,可以通过声明来解决
void addItems(ArrayList<? extends AbstractItem> list)
我不知道什么是kotlin语法。