为何无法调用抽象父类中继承的build()方法?
问题原因分析
报错的核心原因是父类嵌套Builder的访问权限与链式调用的类型不匹配:
- 抽象父类
AbstractGetCommentExpectationTester的嵌套Builder类被定义为protected abstract static class,该权限仅允许同一个包内的类、父类的子类访问,测试类不在这个范围内。 - 父类Builder的所有
set方法返回的是父类Builder类型(AbstractGetCommentExpectationTester.Builder),当你在测试代码中链式调用setExpectedOwnerUsername("mickey")后,返回的实例类型变为父类Builder,而测试类无法访问这个protected类的build()方法,因此触发错误。
两种解决方案
方案1:修改父类Builder的访问权限为public
直接将父类中的嵌套Builder类权限改为public,让测试类可以正常访问其所有方法:
// 父类AbstractGetCommentExpectationTester中的Builder修改为public public abstract static class Builder { protected final String serializedResponseBody; protected String expectedCommentText = "text"; protected int expectedQuestionId = 1; protected int expectedOwnerId = 1; protected String expectedOwnerUsername = "user"; protected Builder(MockHttpServletResponse response) throws UnsupportedEncodingException { this.serializedResponseBody = response.getContentAsString(); } public Builder setExpectedOwnerUsername(String expectedOwnerUsername) { this.expectedOwnerUsername = expectedOwnerUsername; return this; } // 其余set方法和build方法保持不变 }
方案2:子类Builder重写set方法,使用协变返回类型
如果不想改变父类Builder的访问权限,可以在子类GetCommentExpectationTester.Builder中重写所有set方法,返回子类Builder类型,确保链式调用后始终保持子类Builder实例:
public static class Builder extends AbstractGetCommentExpectationTester.Builder { public Builder(MockHttpServletResponse response) throws UnsupportedEncodingException { super(response); } @Override public GetCommentExpectationTester build() { return new GetCommentExpectationTester(this); } // 重写所有set方法,返回子类Builder类型 @Override public Builder setExpectedOwnerUsername(String expectedOwnerUsername) { super.setExpectedOwnerUsername(expectedOwnerUsername); return this; } @Override public Builder setExpectedOwnerId(int expectedOwnerId) { super.setExpectedOwnerId(expectedOwnerId); return this; } @Override public Builder setExpectedQuestionId(int expectedQuestionId) { super.setExpectedQuestionId(expectedQuestionId); return this; } @Override public Builder setExpectedCommentText(String expectedCommentText) { super.setExpectedCommentText(expectedCommentText); return this; } }
内容的提问来源于stack exchange,提问作者Sergey Zolotarev
相关产品推荐
相关产品推荐

