为什么我的if-else语句不能正常工作?

时间:2017-05-04 17:37:52

标签: java if-statement

我有双字段hourlyPayRate和hoursWorked。

我正在尝试编写一个构造函数和mutator来具有特定的条件,那些是不允许支付率低于7.25或大于25.不要让小时工作小于0或大于70.如果值低于最低 传递,然后将字段设置为最小。如果超过最大值,则将字段设置为最大值。

使用我的代码,它的测试是通过7.24,并期望7.25,但我的代码返回7.24。我不明白为什么。该测试还通过将pay设置为8.0,然后将其更改为7.25来检查我的mutator,但是我的代码返回8.0而没有更改,即使它看起来应该返回7.25值。我做错了什么?

public class ProductionWorker extends Employee
{   

private double hourlyPayRate;
private double hoursWorked;

public ProductionWorker(String name, String idNumber, 
String hireDate, ShiftType shift, double hourlyPayRate, double hoursWorked)
{
    super(name, idNumber, hireDate, shift);
    this.hourlyPayRate = hourlyPayRate;
    this.hoursWorked = hoursWorked;

    if (hourlyPayRate > 25)
    {
        hourlyPayRate = 25;
    }
    else if (hourlyPayRate < 7.25)
    {
        hourlyPayRate = 7.25;
    }
    else if (hourlyPayRate < 25 && hourlyPayRate > 7.25)
    {
        this.hourlyPayRate = hourlyPayRate;
    }
    else if (hoursWorked < 0)
    {
        hoursWorked = 0;
    }
    else if (hoursWorked > 70)
    {
        hoursWorked = 70;
    }
}
public double getHourlyPayRate()
{
    return hourlyPayRate;
}


public void setHourlyPayRate(double hourlyPayRate)
{

    //this.hourlyPayRate = hourlyPayRate;

    if (hourlyPayRate > 25)
    {
        hourlyPayRate = 25;
    }
    else if (hourlyPayRate < 7.25)
    {
        hourlyPayRate = 7.25;
    }
    else if (hourlyPayRate < 25 && hourlyPayRate > 7.25)
    {
        this.hourlyPayRate = hourlyPayRate;
    }
}


public double getHoursWorked()
{
    return hoursWorked;
}


public void setHoursWorked(double hoursWorked)
{
    this.hoursWorked = hoursWorked;

    if (hoursWorked < 0)
    {
        hoursWorked = 0;
    }
    else if (hoursWorked > 70)
    {
        hoursWorked = 70;
    }
    else if (hoursWorked > 0 && hoursWorked < 70)
    {
        this.hoursWorked = hoursWorked;
    }
 }
}

另外我认为我应该用if else结束if-else语句,但是当我这样做时,编译器警告我这不是一个声明?

5 个答案:

答案 0 :(得分:1)

    #mainDiv {
      width : 500px;
      height : 550px;
      border : solid 5px rgb( 112, 146, 190 );
      background-color: rgb( 153, 178, 208 );
      border-radius: 5px;
    }
    #boardDiv {
      width : 100%;
      height :100%;
    }
    button {
      background: linear-gradient( white, rgb( 72, 109, 159 ) );
    }

这绝不会超过<html> <head> </head> <body> <div id='mainDiv'> <div id='boardDiv'> </div> <div> <form> Width: <input type="text" name="width" value="10" id="width"> Height: <input type="text" name="hight" value="10" id="height"> Mines: <input type="text" name="mines" value="7" id="mines"> <input type="button" value="New Game" onclick="loadBoard()"> </form> </div> </div> </body> </html>if (...) { doA(); } else if (...) { doB(); } else if (...) { doC(); } doA()中的一个。

您的数据有两个单独的限制条件:工资率必须限制在一定范围内,工作小时数必须在一定范围内。

只用一个doB()语句,您将无法强制执行两个约束。

答案 1 :(得分:1)

为什么final关键字会为您节省无数时间:

进行以下更改,您将了解错误以及下次如何避免错误。

public ProductionWorker(final String name, 
                        final String idNumber,
                        final String hireDate, 
                        final ShiftType shift, 
                        final double hourlyPayRate, 
                        final double hoursWorked)

如果您执行上述操作并使用步骤调试器,您将理解为什么正确的引用语法和逻辑变为:

if (hourlyPayRate > 25) { this.hourlyPayRate = 25; }
else if (hourlyPayRate < 7.25) { this.hourlyPayRate = 7.25; }
else { this.hourlyPayRate = hourlyPayRate; }

if (hoursWorked < 0) { this.hoursWorked = 0; }
else if (hoursWorked > 70) { this.hoursWorked = 70; }
else { this.hoursWorked = hoursWorked; }
  

It is really bad practice to put this much logic in a constructor.   理想情况下,您应该已经在某种程度上完成了此验证   工厂方法/对象模式实现。那说你可以减少   一个内容的代码,它们更明确地说明了它们是什么   在你的具体情况下做得更加可维护。

在这个非常具体的案例中:

您可以通过更简洁地表达代码来减少代码行。

this.hourlyPayRate = Math.min(Math.max(d,7.25), 25.0);
this.hoursWorked = Math.min(Math.max(d,0.0), 70.0);
  

在构造函数中看到的并不是很麻烦。这是   比一堆if/elseif/else更容易推理和维护   语句。

使用normalizeToRange函数,因为两者都做同样的事情。

  

请注意,此处的final关键字与。{1}}关键字一样重要   private关键字,您可以从constructor调用此方法。

private final double normalizeToRange(final double min, final double max, final double d)
{
    return d < min ? min : d > max ? max : d;
}

this.hourlyPayRate = this.normalizeToRange(7.25, 25.0, hourlyPayRate);
this.hoursWorked = this.normalizeToRange(0.0, 70.0, hoursWorked);

对于复杂的If / ElseIf / Else链:

以下是如何应用Chain of Responsibility Pattern来消除过长且复杂的if/elseif/else块的简化示例。

  

我相信会有反对者说这个过于复杂   这种情况,但我认为OP足够错误,这样做   让他们第一次做对。这只是一个稻草人   例如,说明了Pattern的实现   Constraint类可以更通用,更复杂   normalize()在一个地方的默认逻辑。那又怎么样   申请这是一个留给读者的练习。

public class Q43789440
{
    /**
     * Shim/Polyfill for Java < 8 compatibility with Java 8
     *
     * @param <T>
     */
    public interface Predicate<T>
    {
        boolean test(T var1);
    }

    /**
     * Shim/Polyfill for Java < 8 compatibility with Java 8
     *
     * @param <T>
     * @param <F>
     */
    public interface Function<F, T>
    {
        T apply(F var1);

        boolean equals(Object var1);
    }

    public interface Constraint extends Predicate<Double>, Function<Double, Double>
    {
        public Double normalize(final Double input);
    }

    public static class LowerConstraint implements Constraint
    {
        private final Constraint next;

        public LowerConstraint(final Constraint next) { this.next = next; }

        @Override
        public Double normalize(final Double input)
        {
            if (this.test(input)) { return this.apply(input); }
            else { return this.next.normalize(input); }
        }

        @Override
        public boolean test(final Double d)
        {
            return d < 7.25;
        }

        @Override
        public Double apply(final Double d)
        {
            return 7.25;
        }
    }

    public static class UpperConstraint implements Constraint
    {
        private final Constraint next;

        public UpperConstraint(final Constraint next) { this.next = next; }

        @Override
        public Double normalize(final Double input)
        {
            if (this.test(input)) { return this.apply(input); }
            else { return this.next.normalize(input); }
        }

        @Override
        public boolean test(final Double d)
        {
            return d > 25.0;
        }

        @Override
        public Double apply(final Double d)
        {
            return 25.0;
        }
    }

    public static class InRangeConstraint implements Constraint
    {
        @Override
        public Double normalize(final Double input)
        {
            if (this.test(input)) { return this.apply(input); }
            else { throw new IllegalArgumentException(); }
        }

        @Override
        public boolean test(final Double d)
        {
            return d >= 7.25 && d <= 25.0;
        }

        @Override
        public Double apply(final Double d)
        {
            return d;
        }
    }

    public static void main(String[] args)
    {
        final Constraint rules = new LowerConstraint(new UpperConstraint(new InRangeConstraint()));
        for (double d = 0.0; d < 30; d++)
        {
            System.out.printf("%.2f normalized to %.2f", d, rules.normalize(d)).println();
        }
    }
}

答案 2 :(得分:1)

每当你发现自己重写代码时,你应该创建一个方法。这允许您只调用该方法,而不是在多个位置编写相同的代码片段。还有一些错误的if / else语句逻辑。

让我们来看看我们如何稍微改进你的代码,这使得它更容易阅读和调试!

public double hourlyPayRate(double hourlyPayRate) {
    if (hourlyPayRate > 25) {
        hourlyPayRate = 25;
    } else if (hourlyPayRate < 7.25) {
        hourlyPayRate = 7.25;
    }
    return hourlyPayRate;
}

public double hoursWorked(double hoursWorked) {
    if (hoursWorked > 70) {
        hoursWorked = 70;
    } else if (hoursWorked < 0) {
        hoursWorked = 0;
    }
    return hoursWorked;
}

方法首先检查输入是否高于某个值,如果是,则将其设置为该值。否则,它会检查它是否低于某个值。 最后,它返回所述值。由于这些测试已经完成,因此您无需检查它是否位于最低范围和最高范围之间。

答案 3 :(得分:1)

问题是在构造函数中,您只设置了hourlyPayRate和hoursWorked一次。

this.hourlyPayRate = hourlyPayRate;
this.hoursWorked = hoursWorked;

在if-else语句中,您是具有实例变量赋值的参数赋值。由于构造函数参数与私有实例变量共享相同的名称。您必须使用this运算符将它们分配给对象。

public ProductionWorker(String name, String idNumber, 
    String hireDate, ShiftType shift, double hourlyPayRate, double hoursWorked)

{
    super(name, idNumber, hireDate, shift);
    this.hourlyPayRate = hourlyPayRate;
    this.hoursWorked = hoursWorked;

if (hourlyPayRate > 25)
{
    this.hourlyPayRate = 25;
}
else if (hourlyPayRate < 7.25)
{
    this.hourlyPayRate = 7.25;
}
else if (hourlyPayRate < 25 && hourlyPayRate > 7.25)
{
    this.hourlyPayRate = hourlyPayRate;
}
else if (hoursWorked < 0)
{
    this.hoursWorked = 0;
}
else if (hoursWorked > 70)
{
    this.hoursWorked = 70;
}

同样的问题适用于setHoursWorked(double hoursWorked)

public void setHoursWorked(double hoursWorked) {     this.hoursWorked = hoursWorked;

if (hoursWorked < 0)
{
    this.hoursWorked = 0;
}
else if (hoursWorked > 70)
{
    this.hoursWorked = 70;
}
else if (hoursWorked > 0 && hoursWorked < 70)
{
    this.hoursWorked = hoursWorked;
}

答案 4 :(得分:0)

首先,您需要了解变量范围。在您的方法中,hourlyPayRate引用参数,this.hourlyPayRate引用类实例变量。从方法返回后,分配给hourlyPayRate的值将会丢失。

你的setHourlyPayRate mutator看起来应该更像这样:

public void setHourlyPayRate(double hourlyPayRate)
{
    if (hourlyPayRate > 25)
    {
        this.hourlyPayRate = 25;
    }
    else if (hourlyPayRate < 7.25)
    {
        this.hourlyPayRate = 7.25;
    }
    else
    {
        this.hourlyPayRate = hourlyPayRate;
    }
}

这会根据参数的值为类变量分配正确的值。避免这种混淆的一种方法是为内部变量和参数指定不同的名称。

代码的第二个问题是构造函数中的if .. else if语句。 else if部分仅在先前条件为假时才会执行。在您的情况下,hoursWorked仅在hourlyPayRate正好为25或7.25时进行测试,因为这两个确切的值未在之前的if语句中进行过测试。