如何覆盖扩展类的子方法

时间:2019-05-11 13:22:11

标签: java spring spring-mvc amazon-dynamodb

我想将基本实体扩展为兼容的DynamoDB文档,但是我不知道如何扩展实体的子级。这是代码:

@Data
@Accessors(chain = true)
@ApiModel
public class Question {

    @NotNull
    @ApiModelProperty(value = "UUID", required = true)
    private UUID id;

    @NotBlank
    private String name;

    @ApiModelProperty(value = "List of answers")
    private List<Answer> answers = Collections.emptyList();

}

@Data
@Accessors(chain = true)
@ParametersAreNonnullByDefault
public class Answer {

    @NotNull
    @ApiModelProperty(value = "Question key", required = true)
    private UUID questionKey;

    @NotBlank
    @ApiModelProperty(value = "Answer in string format", required = true)
    private String value;
}

以下是扩展的“答案发电机”文档:

@DynamoDBTable(tableName = "question")
public class QuestionDocument extends Question {

    @DynamoDBHashKey
    @DynamoDBAutoGeneratedKey
    @Override
    public UUID getId() {
        return super.getId();
    }

    @DynamoDBAttribute
    @Override
    public Long getName() {
        return super.getName();
    }

    @DynamoDBAttribute
    @Override
    // Here is the problem, I don't know how to properly override answers, because this method expect Answer output.
    public Set<AnswerDocument> getAnswers() {
        return super.getAnswers();
    }
}

@DynamoDBDocument
@NoArgsConstructor
public class AnswerDocument extends Answer {

    @DynamoDBAttribute
    @Override
    public Long getValue() {
        return super.getValue();
    }
}

问题是我不知道如何正确地覆盖扩展的QuestionDocument的getAnswers()方法以返回扩展的AnswerDocument。

请把我放在正确的轨道上,如何在上面的示例中显示继承性。

谢谢。

2 个答案:

答案 0 :(得分:1)

来自Java文档:

  

“子类重写方法的能力允许类从行为“足够接近”的超类继承,然后根据需要修改行为。重写方法具有相同的名称,数量和类型的参数,并返回类型作为其覆盖的方法。覆盖方法还可以返回被覆盖方法返回的类型的子类型。该子类型称为协变返回类型。“

因此,因为AnswerDocument扩展了Answer,所以在覆盖具有返回类型AnswerDocument的方法的方法中返回类型Answer很好。

但是,我不认为您只想在这里致电super,因为它会为您提供Answer的列表,而这似乎并不是您想要的行为。因此,如果您需要超级行为,请接收Answer的列表,进行转换,然后返回AnswerDocument的列表。

@DynamoDBAttribute
@Override
public List<AnswerDocument> getAnswers() {
    List<Answer> answerlist = super.getAnswers();
    // transform them to AnswerDocument
    return answerDocumentList ;
}

此示例假定您的AnswerDocuments首先作为Answers出现,然后进行转换。如果QuestionDocument不包含任何答案,那么super方法将根本无法为您服务,并且您必须自己编写代码,但是您仍然可以使用覆盖原始{{ 1}},但返回类型为getAnswers()

答案 1 :(得分:0)

您需要将返回类型更改为Collection,因为ListSet属于不同的层次结构。
我进行了一些更改,请检查下面的代码片段,让我知道它是否符合您的要求。

注意:为简便起见,我删除了其他注释。

父类:

class Question {

    private UUID id;

    private Long name;

    private List<Answer> answers = Collections.emptyList();

    // Change in the return type
    public Collection<Answer> getAnswers() {
        return answers;
    }

    public void setAnswers(List<Answer> answers) {
        this.answers = answers;
    }
}

儿童班:

public class QuestionDocument extends Question {

    @Override
    public Collection<AnswerDocument> getAnswers() {
        return super.getAnswers();
    }
}