在方法覆盖中使用子类型参数

时间:2016-01-21 07:48:47

标签: java covariance

public abstract class SequenceItemHolder {

    public SequenceItemHolder(View itemView) {
    }

    public abstract void setData(SequenceRowElement.RowElement rowElement);


        public static class TesteItemHolder extends SequenceItemHolder {

        public TesteItemHolder(View itemView) {
        }

        @Override
        public void setData(SequenceRowElement.TestRowElement rowElement) {
        }
   }
}

请有人解释我为什么在覆盖中出现编译错误?

请问如何修复它(不使用界面)?

注意: TestRowElement扩展RowElement

4 个答案:

答案 0 :(得分:5)

错误1

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

对象没有将View作为参数的构造函数。删除超级电话。

错误2

public abstract void setData(SequenceRowElement.RowElement rowElement) {}

抽象方法不应该有一个正文。用它替换它:

public abstract void setData(SequenceRowElement.RowElement rowElement);

错误3

您的overriden方法应该与抽象方法具有相同的参数类型。

答案 1 :(得分:2)

你没有覆盖方法(=相同的方法签名),你正在重载它(=相同的方法名称,不同的参数)

public abstract void setData(SequenceRowElement.RowElement rowElement) {}

@Override
public void setData(SequenceRowElement.TestRowElement rowElement) {
}

您的第一个函数(在SequenceItemHolder中)以SequenceRowElement.RowElement为参数,第二个函数为SequenceRowElement.TestRowElement。 因此,@Override是错误的。

答案 2 :(得分:2)

这是关于正式称为covariance and contravariance的内容。

简单地说,如果您的类型层次结构为Animal> Mammal> Dog和基本方法

Mammal foo(Mammal arg)

允许这些作为覆盖:

  • Mammal foo(Mammal arg)
    
  • Mammal foo(Animal arg)
    
  • Dog    foo(Mammal arg)
    
  • Dog    foo(Animal arg)
    

也就是说,您可以扩展参数类型(允许在子类'方法中使用更多常规输入)并缩小返回值(声明您将返回更具体的类型)。

原因是,调用者必须能够使用原始签名调用overriden方法 - 因此子类方法不能具有更多特定参数,也不能具有更一般的返回值。在上面的示例中,调用者必须能够使用类型foo的参数调用Mammal并且返回值必须是Mammal - 子类方法中的参数因此可能是{{1或Mammal(两者都接受Animal类型的实际参数),并且可以返回MammalMammal(两者都可以存储在类型的变量中) Dog)。

答案 3 :(得分:1)

类似的东西:

    public abstract class SequenceItemHolder {

    public SequenceItemHolder(View itemView) {
    }

    public abstract void setData(SequenceRowElement.RowElement rowElement);

    public static class TesteItemHolder extends SequenceItemHolder {

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

        @Override
        public void setData(SequenceRowElement.RowElement rowElement) {          
        }
    }
}