【发布时间】:2016-03-17 09:54:43
【问题描述】:
我有三门课
abstract class Animal {...}class Shark extends Animal {...}class Hammerhead extends Shark {...}
这些类中的每一个都有一个静态的内部 _Builder 类。这些是标准构建器类,但它们相互扩展以允许在实例化时对对象进行完整配置。例如建设者的使用可能看起来像
Hammerhead.getBuilder().setColor(color.GREY).setFinSize(1.3f).setHammerSize(.9f).build();
这将返回 Hammerhead 的新实例
最初我遇到了上述问题,因为例如setColor() 会返回一个 Animal.ABuilder,我不能随后调用 setFinSize() on(这是一个 Animal.ABuilder em>Shark.Sbuilder).
答案很适合扩展一个孩子,但我遇到的问题超出了孙辈的建设者。
这里是构建者的类签名,就像我拥有的那样static class ABuilder<B extends ABuilder<B>>{...}static class SBuilder<B extends SBuilder<B>> extends ABuilder<B extends ABuilder<B>>{...}static class HBuilder<B extends HBuilder<B>> extends SBuilder<B extends SBuilder<B>>{...}
不幸的是,这给了我编译错误。
类型参数“B”不在其范围内;应该延长 'Animal.ABuilder'
此错误针对 SBuilder 定义中的第三个也是最后一个 B
有没有办法做到这一点?
谢谢!
来源
Animal.java
package com.example;
public abstract class Animal {
String color;
public Animal(ABuilder builder){
this.color = builder.color;
}
public static class ABuilder<B extends ABuilder<B>> {
String color;
public B setColor(String c){
color = c;
return (B)this;
}
}
}
Shark.java
package com.example;
public class Shark extends Animal {
float fin_size;
public Shark(SBuilder builder){
super(builder);
fin_size = builder.fins;
}
// Problems are in this general area: \/
public static class SBuilder<B extends SBuilder<B>> extends ABuilder<B extends ABuilder<B>>{
float fins;
public B setFinSize(float size){
this.fins = size;
return (B) this;
}
public Shark build(){
return new Shark(this);
}
}
}
Hammerhead.java
package com.example;
public class Hammerhead extends Shark {
float hammer;
public Hammerhead(HBuilder builder) {
super(builder);
hammer = builder.hammer;
}
public static HBuilder<? extends HBuilder> getBuilder(){
return new HBuilder<HBuilder>();
}
public static class HBuilder<B extends HBuilder<B>> extends SBuilder<B extends SBuilder<B>> { {
float hammer;
public B setHammerSize(float hammer) {
this.hammer = hammer;
return (B)this;
}
public Hammerhead build(){
return new Hammerhead(this);
}
}
}
编辑
根据 Seelenvirtuose 的回答:
你的回答对我来说很有意义。我以为我已经解决了问题,但现在我已经做出了更改,它仍然无法按预期工作:
在第一次调用 setColor() 之后,返回的类型(由 Intellij IDEA 报告)就是定义函数的任何类。
每一行的注释都是函数调用返回的类型
Hammerhead hh =
Hammerhead.getBuilder() // HBuilder<? extends HBuilder> //
.setColor("Black") // ? extends com.example.Hammerhead.HBuilder
.setHammerSize(10f) // HBuilder
.setFinSize(10f) // SBuilder
.setColor("Fuschia") // ABuilder
.setFinSize(10f) // Error: No such method on ABuilder
.build(); // Also does not work because build()
// should be called on an HBuilder
编辑 2
解决方案有效。经过一番摸索后,我意识到我的 getBuilder() 方法存在第二个问题,这导致了进一步的问题。回家后我会编辑以上内容以反映正确的功能和解决方案。
最终编辑
getBuilder 函数应该是
public static HBuilder<? extends HBuilder<?>> getBuilder(){
return new HBuilder<>();
}
【问题讨论】:
标签: java generics polymorphism subclass builder