gpt4 book ai didi

java - 具有相同的删除,但都不会覆盖仅在一种情况下出现的其他警告

转载 作者:搜寻专家 更新时间:2023-11-01 08:30:39 26 4
gpt4 key购买 nike

我正在扩展抽象类 RecyclerView.Adapter:

public static abstract class Adapter<VH extends ViewHolder> {
public abstract VH onCreateViewHolder(ViewGroup parent, int viewType);

public abstract void onBindViewHolder(VH holder, int position);

// some more code
}

进入另一个抽象类:

public abstract class Adapter<VH extends RecyclerView.ViewHolder> extends RecyclerView.Adapter<RecyclerView.ViewHolder> {

public abstract VH onCreateViewHolder(ViewGroup parent, int viewType);

public abstract void onBindViewHolder(VH viewHolder, int position);

}

但是当我这样做时,只有 onBindViewHolder 方法显示错误:

'onBindViewHolder(VH, int)' in 'com.leonardo.endlessrecycerviewwithsqlitepagination.adapter.ViewHolder' clashes with 'onBindViewHolder(VH, int)' in 'android.support.v7.widget.RecyclerView.Adapter'; both methods have same erasure, yet neither overrides the other

为什么 onCreateViewHolder 方法没有发生同样的事情?

这个场景还有一个问题:

public abstract class Adapter<VH extends RecyclerView.ViewHolder> extends RecyclerView.Adapter<ViewHolder.CustomViewHolder> {

public abstract VH onCreateViewHolder(ViewGroup parent, int viewType);

public abstract void onBindViewHolder(VH holder, int position);

static class CustomViewHolder extends RecyclerView.ViewHolder {

public CustomViewHolder(View itemView) {
super(itemView);
}
}
}

为什么现在两种方法都显示上面的错误?

最佳答案

问题是您没有将自己的抽象类参数传播到链的顶部;你在做什么:

public abstract class Adapter<VH extends RecyclerView.ViewHolder> extends RecyclerView.Adapter<RecyclerView.ViewHolder>

为了减少混淆,我们将 Adapter 的泛型参数称为 VH2;那么,我们有:

public abstract class Adapter<VH2 extends RecyclerView.ViewHolder> extends RecyclerView.Adapter<RecyclerView.ViewHolder>

public static abstract class Adapter<VH extends ViewHolder>

所以继承自RecyclerView.Adapter的方法必须是VH类型,而不是VH2!看到不同?在您的抽象实现中,VH = RecyclerView.ViewHolder。所以凡是有 VH 的地方,您现在必须放置 RecyclerView.ViewHolder 而不是 VH2。

您可能会问,为什么其中一种方法“有效”而另一种无效?

嗯,那是因为 OOP 的工作原理。观察您的 VH2 被定义为扩展 RecyclerView.ViewHolder。所以 VH2 RecyclerView.ViewHolder。

所以如果一个父方法返回一个VH,你可以在你的继承中,指定它返回什么样的VH;在这种情况下,VH2 是一个 VH,因此您可以安全地执行以下操作:

public abstract VH onCreateViewHolder(ViewGroup parent, int viewType);

举个例子:

public abstract class Farm {
Animal abstract getAnimal();
}

public class Abattoir extends Farm {
@Override
Pig getAnimal() { ... }
}

没关系!屠宰场总是按照农场的要求返回动物,因为 pig 是动物!

现在让我们考虑另一种方法:

public abstract void onBindViewHolder(VH viewHolder, int position);

这里parent要求参数类型为VH = ViewHolder。在这种情况下,你不能把更具体的东西放在 child 身上! parent 要求每个 child 都知道如何处理每个可能的 ViewHolder,而不仅仅是那些扩展 ViewHolder 的 VH2。在这里你可以更通用,但不能更具体!例如:

public abstract class Animal {
abstract void eat(Food f);
}

public class Pig extends Animal {
@Override
void eat(Carrot c) { ... }
}

这行不通!通过扩展 Animal,您必须遵守它的要求! Animal要求每个动物都必须有一个eat方法,可以吃任何食物,而不仅仅是胡萝卜。想象一下我这样做了:

Animal a = new Pig();
// ...
a.eat(wheat); // ??

会发生什么?因此,正如您所见,使用参数可以更通用,但不能更具体。对于返回类型,您可以更具体,但不能更通用。因为parent contract要求你收A退B,你要收的多于A,或者退的少于B,没关系,你说了算。但是您必须至少收到 A,最多返回 B。这就是 OOP 的工作原理。

所以你的问题只是伪装成泛型,但范围更广;)

关于java - 具有相同的删除,但都不会覆盖仅在一种情况下出现的其他警告,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41226836/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com