具有相同的擦除,但都不会覆盖仅在一种情况下出现的其他警告
Have same erasure, yet neither overrides the other warning appearing in only ONE situation
我正在扩展摘要class 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
}
进入另一个摘要class:
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);
}
}
}
为什么现在两种方法都显示上面的错误?
问题是您没有将自己的抽象 class' 参数传播到链的顶部;你在做什么:
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.
为什么其中一种方法 'work' 而另一种方法不行,您可能会问?
嗯,那是因为 OOP 的工作原理。观察您的 VH2 被定义为扩展 RecyclerView.ViewHolder。所以VH2是RecyclerView.ViewHolder.
所以如果一个parent方法returns一个VH,你可以在你的继承中,指定 returns 是什么类型的 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() { ... }
}
没关系!根据农场的要求,屠宰场总是 return 动物,因为猪是动物!
现在让我们考虑另一种方法:
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); // ??
会发生什么?因此,正如您所见,使用参数可以更通用,但不能更具体。使用 return 类型,您可以更具体,但不能更通用。因为 parent 合同要求你收到 A 和 return B。如果你想收到比 A 多,或者 return 比 B 少,没关系,这是你的决定。但是你必须至少收到 A,并且 return 最多收到 B。这就是 OOP 的工作原理。
所以你的问题只是伪装成泛型,但范围更广;)
我正在扩展摘要class 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
}
进入另一个摘要class:
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);
}
}
}
为什么现在两种方法都显示上面的错误?
问题是您没有将自己的抽象 class' 参数传播到链的顶部;你在做什么:
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.
为什么其中一种方法 'work' 而另一种方法不行,您可能会问?
嗯,那是因为 OOP 的工作原理。观察您的 VH2 被定义为扩展 RecyclerView.ViewHolder。所以VH2是RecyclerView.ViewHolder.
所以如果一个parent方法returns一个VH,你可以在你的继承中,指定 returns 是什么类型的 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() { ... }
}
没关系!根据农场的要求,屠宰场总是 return 动物,因为猪是动物!
现在让我们考虑另一种方法:
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); // ??
会发生什么?因此,正如您所见,使用参数可以更通用,但不能更具体。使用 return 类型,您可以更具体,但不能更通用。因为 parent 合同要求你收到 A 和 return B。如果你想收到比 A 多,或者 return 比 B 少,没关系,这是你的决定。但是你必须至少收到 A,并且 return 最多收到 B。这就是 OOP 的工作原理。
所以你的问题只是伪装成泛型,但范围更广;)