使用构造函数的泛型 and/or 对象到 return 超类或子类
Using generics and/or objects of Constructor to return superclass OR subclass
总结:是否可以让不同参数的构造函数在一个方法中创建不同subclasses的对象?
我有一个(非抽象的)class 和一个子class 扩展它。 subclass 有一个附加字段。
两者都是不可变的:
class Superclass{
final Type type; // Type is an enum; It has a final double decayFactor for each type.
final int amount;
Superclass(Type type, int amount){//simple constructor initializing final fields
...
}
//decay method talked about below is implemented here
}
class Subclass extends Superclass{
final boolean additionalProperty;
Subclass(Type type, int amount, boolean additionalProperty){
super(type, amount);
this.additionalProperty = additionalProperty;
}
}
现在我想要一个方法,其中 return 是具有更新数量的相同 class(Subclass
或 Superclass
)的对象。
此方法应按枚举 Type
定义的特定百分比减少 amount
。
这个简单的方法可能看起来像那样(在 Superclass
中实现):
public Superclass decay(){
return new Superclass(type, amount * type.getDecayFactor())
}
现在我的问题是,如果我有一个 Subclass
并调用此方法,将在一个方法中 return 一个 Superclass
。我会丢失存储在 additionalProperty
中的信息。
所以我想到了其他方法来解决这个问题。最简单的方法是在 Subclass
中覆盖 decay()
。但是,我发现我不能强制 subclass 覆盖此方法。因此,如果稍后添加其他子 classes,如果他们不实现它,可能会发生相同的信息丢失。
所以我试图通过使用泛型来获取 class:
的构造函数来解决这个问题
public <T extends Superclass> Superclass decay() throws ...[Many exceptions]{
int newAmount = type.getDecayFactor() * amount;
Constructor<? extends Superclass> constructor = this.getClass().getConstructor(Type.class, int.class);
return constructor.newInstance(type, amount);
}
我试过了,但未能使用通用 T
而不是 this.getClass()
。
但是,这也行不通。我仍然必须覆盖它,因为 Subclass(Type, int) 不存在。
我的想法是,如果我能以某种方式获得 class 的所有字段,我可以调用 subclasses 或 superclass 的(唯一)构造函数并传递它需要的所有值, 仅修改量。我试图通过使用 this.getClass().getFields()
来获取匹配的构造函数,但它说: ... getConstructor() ... 不适用于参数字段 []。(我需要字段的类型吗?)
我的问题:这可能吗?这是一个优雅的或受欢迎的实现吗?或者你应该更好地说明 subclasses 必须覆盖 decay(),恕我直言,哪个更简单易读?这里是否需要泛型?(我慢慢开始认为不需要...)
附加信息:我首先将 Superclass 和 Subclass 作为抽象,并且对于每个 Type
枚举自己的 subclass 扩展那些(Superclass
或 Subclass
)。但是我将不得不为每个 classes 编写非常相似的代码。所以我把那些包含的信息放入一个带有最终字段的枚举中。(很容易有 100 个 classes 代表类似的东西)
decay() 方法旨在像这样使用来“修改”不可变的 Superclass
/Subclass
:
Superclass someObject = newSuperclass/Subclass
...
someObject = someObject.decay();
非常感谢您的回答。
我相信重写该方法应该可以正常工作。您可以更改 decay()
的 return 类型,只要它是 Superclass
的 sub-type。
您还可以在单独的方法中隔离计算衰减逻辑以避免冗余代码。
class Superclass {
final double rate;
final int amount;
Superclass(double rate, int amount) {
this.rate = rate;
this.amount = amount;
}
public Superclass decay() {
return new Superclass(this.rate, this.calcuateDecay());
}
protected int calcuateDecay() {
return (int) (this.amount * this.rate);
}
}
class Subclass extends Superclass {
final boolean additionalProperty;
Subclass(double rate, int amount, boolean additionalProperty) {
super(rate, amount);
this.additionalProperty = additionalProperty;
}
@Override
public Subclass decay() {
return new Subclass(this.rate, this.calcuateDecay(), this.additionalProperty);
}
}
看到它工作 here。
在这里覆盖是可选的。为了进一步加强类型安全,泛型接口可以定义如下
interface <T extends Superclass> Decayable<T> {
T decay();
}
Superclass
可以实现Decayable<Superclass>
,Subclass
可以实现Decayable<Subclass>
。查看实际效果 here。
总结:是否可以让不同参数的构造函数在一个方法中创建不同subclasses的对象?
我有一个(非抽象的)class 和一个子class 扩展它。 subclass 有一个附加字段。 两者都是不可变的:
class Superclass{
final Type type; // Type is an enum; It has a final double decayFactor for each type.
final int amount;
Superclass(Type type, int amount){//simple constructor initializing final fields
...
}
//decay method talked about below is implemented here
}
class Subclass extends Superclass{
final boolean additionalProperty;
Subclass(Type type, int amount, boolean additionalProperty){
super(type, amount);
this.additionalProperty = additionalProperty;
}
}
现在我想要一个方法,其中 return 是具有更新数量的相同 class(Subclass
或 Superclass
)的对象。
此方法应按枚举 Type
定义的特定百分比减少 amount
。
这个简单的方法可能看起来像那样(在 Superclass
中实现):
public Superclass decay(){
return new Superclass(type, amount * type.getDecayFactor())
}
现在我的问题是,如果我有一个 Subclass
并调用此方法,将在一个方法中 return 一个 Superclass
。我会丢失存储在 additionalProperty
中的信息。
所以我想到了其他方法来解决这个问题。最简单的方法是在 Subclass
中覆盖 decay()
。但是,我发现我不能强制 subclass 覆盖此方法。因此,如果稍后添加其他子 classes,如果他们不实现它,可能会发生相同的信息丢失。
所以我试图通过使用泛型来获取 class:
public <T extends Superclass> Superclass decay() throws ...[Many exceptions]{
int newAmount = type.getDecayFactor() * amount;
Constructor<? extends Superclass> constructor = this.getClass().getConstructor(Type.class, int.class);
return constructor.newInstance(type, amount);
}
我试过了,但未能使用通用 T
而不是 this.getClass()
。
但是,这也行不通。我仍然必须覆盖它,因为 Subclass(Type, int) 不存在。
我的想法是,如果我能以某种方式获得 class 的所有字段,我可以调用 subclasses 或 superclass 的(唯一)构造函数并传递它需要的所有值, 仅修改量。我试图通过使用 this.getClass().getFields()
来获取匹配的构造函数,但它说: ... getConstructor() ... 不适用于参数字段 []。(我需要字段的类型吗?)
我的问题:这可能吗?这是一个优雅的或受欢迎的实现吗?或者你应该更好地说明 subclasses 必须覆盖 decay(),恕我直言,哪个更简单易读?这里是否需要泛型?(我慢慢开始认为不需要...)
附加信息:我首先将 Superclass 和 Subclass 作为抽象,并且对于每个 Type
枚举自己的 subclass 扩展那些(Superclass
或 Subclass
)。但是我将不得不为每个 classes 编写非常相似的代码。所以我把那些包含的信息放入一个带有最终字段的枚举中。(很容易有 100 个 classes 代表类似的东西)
decay() 方法旨在像这样使用来“修改”不可变的 Superclass
/Subclass
:
Superclass someObject = newSuperclass/Subclass
...
someObject = someObject.decay();
非常感谢您的回答。
我相信重写该方法应该可以正常工作。您可以更改 decay()
的 return 类型,只要它是 Superclass
的 sub-type。
您还可以在单独的方法中隔离计算衰减逻辑以避免冗余代码。
class Superclass {
final double rate;
final int amount;
Superclass(double rate, int amount) {
this.rate = rate;
this.amount = amount;
}
public Superclass decay() {
return new Superclass(this.rate, this.calcuateDecay());
}
protected int calcuateDecay() {
return (int) (this.amount * this.rate);
}
}
class Subclass extends Superclass {
final boolean additionalProperty;
Subclass(double rate, int amount, boolean additionalProperty) {
super(rate, amount);
this.additionalProperty = additionalProperty;
}
@Override
public Subclass decay() {
return new Subclass(this.rate, this.calcuateDecay(), this.additionalProperty);
}
}
看到它工作 here。
在这里覆盖是可选的。为了进一步加强类型安全,泛型接口可以定义如下
interface <T extends Superclass> Decayable<T> {
T decay();
}
Superclass
可以实现Decayable<Superclass>
,Subclass
可以实现Decayable<Subclass>
。查看实际效果 here。