繁体   English   中英

更好地更改父母的领域或覆盖吸气剂?

[英]Better to change parent's field or override getter?

假设我有一个Projectile类,它充当游戏中所有弹丸的基类。 它包含最大速度,重力系数,反弹系数等的默认值。

public abstract class Projectile {

    protected float maxSpeed = 100.0f;
    protected float gravityCoefficient = 1.0f;
    protected float bounceCoefficient = 1.0f;
    ...

}

然后,我有一堆子类,每个子类都可以选择重写某些默认值。

哪种方法更好?

1.在子构造函数中设置字段值

public class Arrow {

    public Arrow(){
        super();
        maxSpeed = 200.0f;
    }

}

2.让孩子覆盖吸气剂

public class Arrow {

    public float getMaxSpeed(){
        return 200.0f;
    }

}

我倾向于说第一种方法更好,因为这意味着可以直接访问该字段,而无需任何额外的函数调用。 但是,这确实意味着该值在对象创建期间设置了两次,一次由父级设置,一次由子级设置。

我在这里想念什么吗? 也许还有另一种方法?

直观地讲,任何特定弹丸的最大速度在其生命周期内都不太可能发生变化(即使在相同类型的不同实例可以具有不同的最大速度的情况下),因此,我希望最终使用它。 我也希望将其定型-除了真正的常量之外,我很少使用非私有字段。

当您具有Projectile某些状态(字段)时,我将避免让getMaxSpeed揭示出与字段不同而导致的最大速度的混淆。

我可能会这样设计:

public abstract class Projectile {
    private final float maxSpeed;

    protected Projectile(float maxSpeed) {
        this.maxSpeed = maxSpeed;
    }

    // Only if you really need this...
    protected Projectile() {
        this(200f);
    }

    public final getMaxSpeed() {
        return maxSpeed;
    }
}

public class Arrow extends Projectile {
    public Arrow() {
        super(100f);
    }
}

可以用类似的方式来处理引力系数和弹跳系数-或如果所有这些真的都充当“对于特定类型的每个实例相同的值”,则可以引入一个新类来表示这些常数,从而将变化的状态分开从常量限制/系数中提取类型的实例-每个实例可能只是对该​​新类的实例的最终引用。 不幸的是,Java(以及至少一些类似的语言)并不能很好地模拟这种层次结构。 总是很烦人:(

您应该有一个二传手并使用它,这就是二传手的用途。 它将允许您将字段保持私有状态。 另一个好处是,使用Java Bean约定将允许您使用诸如Apache Commons BeanUtils之类的库来填充和操作对象。 您还可以将数据持久保存在数据库或文件中。

public abstract class Projectile {

    private float maxSpeed = 100.0f;  // default 

    protected void setMaxSpeed(float newSpeed) {
        maxSpeed = newSpeed;
    }
}

public class Arrow extends Projectile {

    public Arrow() {
        super();
        setMaxSpeed(200.0f);  // arrow specific values
    }
}

第一种方法。 在抽象基类中声明一个名为ModifyDefaults()的方法。 在每个类中实现它并在构造函数中调用,以便每当有人看到抽象类时,都可以得出结论,您将修改子级中的默认值。
或者,如果只有几个决定性参数,则只需将Projectile创建的职责移交给projectileFactory。

您倾向于第一个答案。 它确实明确指出以下内容:

  • 子类负责创建自己的实例变量(属性)

  • 尽管在某些观点上听起来不错,但重写吸气剂通常不能提供良好的可维护性。 构造函数很清楚地声明了额外的一组属性默认值。

我不确定您的设计,但是如果您拥有的超类没有自己的状态,请尝试使其abstract ,并且设计会比我们在那种情况下所讨论的完全更改(那时候可以考虑选项2) 。

对于Java,编译器优化和JIT优化对于提高性能非常重要。
第二段代码将更容易优化,无需担心额外的操作。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM