[android]有相同的擦除,但既不会覆盖其他警告出现在只有一种情况

发布时间: 2017/3/19 17:45:18
注意事项: 本文中文内容可能为机器翻译,如要查看英文原文请点击上面连接.

我扩展抽象类 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)',在 'com.leonardo.endlessrecycerviewwithsqlitepagination.adapter.ViewHolder' 与 'onBindViewHolder (VH,int)',在 'android.support.v7.widget.RecyclerView.Adapter'; 冲突这两种方法有相同的擦除,但都不会互相替代

为什么同样的事情不会发生对 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);
        }
    }
}

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

解决方法 1:

问题是链的你不传播你自己抽象类参数;你正在做:

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

若要使这不那么令人困惑,让我们调用适配器的泛型参数 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 type ,不 VH2 !看到的差异吗?在你的抽象实现 VH = RecyclerView.ViewHolder。所以到处都有重链可变区,你必须现在就 RecyclerView.ViewHolder 而不是 VH2。

和为什么的方法 '工作',另一个不是,你可能会问?

嗯,那是因为面向对象的工作原理。观察你的 VH2 被定义为扩展 RecyclerView.ViewHolder。所以 VH2 RecyclerView.ViewHolder。

所以如果父方法返回重链可变区,你可以在你继承中,指定什么样的 VH 它返回;在这种情况下,VH2 是重链可变区,所以你可以做︰

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

看这个例子︰

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

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

没关系!屠场始终返回一种动物,因为农场需要,因为猪是动物 !

现在让我们想想另一种方法︰

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

在这里,父母需要的参数是 type VH = ViewHolder。在这种情况下,你不能把一些更具体的子元素 !父要求每个子元素知道如何处理每个可能的 ViewHolder,不只是这些扩展 ViewHolder 的 VH2。在这里你可以成为你想要的但不能更具体更通用 !例如︰

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

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

这行不通 !通过扩展的动物,你必须遵守其要求 !动物需要每个动物都有可以吃任何食物,不只是胡萝卜吃方法。想象我这样做︰

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

会发生什么?所以正如你所看到的与参数你可以更通用,但不能更具体。返回类型,您可以更加具体,但不是更多的泛型。因为父合同要求您收到 A 并返回 B.如果你想要得到更多,或返回小于 B,这是好的它是你的电话。但你必须接受至少一,和在大多数 B.返回这就是面向对象的工作原理。

所以你的问题只是伪装的仿制药,但它远远;)

官方微信
官方QQ群
31647020