来自另一个stackoverflow线程link的示例:
public class RegularEmployee {
private BigDecimal salary;
public void setSalary(BigDecimal salary) {
this.salary = salary;
}
public static BigDecimal getBonusMultiplier() {
return new BigDecimal(".02");
}
public BigDecimal calculateBonus() {
return salary.multiply(getBonusMultiplier());
}
/* ... presumably lots of other code ... */
}
public class SpecialEmployee extends RegularEmployee {
public static BigDecimal getBonusMultiplier() {
return new BigDecimal(".03");
}
}
这不像某些人可能会想到的那样,因为calculateBonus
始终从getBonusMultiplier
获取RegularEmployee
,即使是从SpecialEmployee
的实例调用。
public class RegularEmployee {
private BigDecimal salary;
public void setSalary(BigDecimal salary) {
this.salary = salary;
}
public static BigDecimal getBonusMultiplier() {
return new BigDecimal(".02");
}
public BigDecimal calculateBonus() {
try {
return salary.multiply((BigDecimal) this.getClass().getMethod("getBonusMultiplier").invoke(null));
} catch (NoSuchMethodException | SecurityException | IllegalAccessException | IllegalArgumentException | InvocationTargetException ex) {
Logger.getLogger(Parent.class.getName()).log(Level.SEVERE, null, ex);
}
}
/* ... presumably lots of other code ... */
}
public class SpecialEmployee extends RegularEmployee {
public static BigDecimal getBonusMultiplier() {
return new BigDecimal(".03");
}
}
如果从getBonusMultiplier()
实例调用,则会从SpecialEmployee
调用SpecialEmployee
。
我的问题是:为什么Java不提供隐式使用Method类'这样调用?如果我可以通过以下方式实现相同的代码,那么代码将更具可读性:
public class RegularEmployee {
private BigDecimal salary;
public void setSalary(BigDecimal salary) {
this.salary = salary;
}
public static BigDecimal getBonusMultiplier() {
return new BigDecimal(".02");
}
public BigDecimal calculateBonus() {
return salary.multiply(origin.getBonusMultiplier());
}
/* ... presumably lots of other code ... */
}
public class SpecialEmployee extends RegularEmployee {
public static BigDecimal getBonusMultiplier() {
return new BigDecimal(".03");
}
}
编辑:所以看起来人们认为我的设计很糟糕。因此,我会尝试改进它:
public class RegularEmployee {
private BigDecimal salary;
protected bonusMultiplier;
public RegularEmployee(){
bonusMultiplier = getBonusMultiplier();
}
public void setSalary(BigDecimal salary) {
this.salary = salary;
}
public static BigDecimal getBonusMultiplier() {
return new BigDecimal(".02");
}
public BigDecimal calculateBonus() {
return salary.multiply(bonusMultiplier);
}
/* ... presumably lots of other code ... */
}
public class SpecialEmployee extends RegularEmployee {
public SpecialEmployee(){
bonusMultiplier = getBonusMultiplier();
}
public static BigDecimal getBonusMultiplier() {
return new BigDecimal(".03");
}
}
它有效,它不会滥用Reflection并为getBonusMultiplier提供可自定义性,就像原始示例一样。关于这段代码我只有一件事我不喜欢:必须将RegularEmployee的构造函数中的代码复制到SpecialEmployee的构造函数中。我知道由于隐藏了父方法,它们在语义上是不同的,但我仍然不需要复制代码。任何人都可以给我一个解决方案,而无需复制代码? (换句话说:任何人都可以给我一个懒惰的程序员解决方案吗?:P)