如何在不使用setter的情况下从子类访问超类中的私有字段?

时间:2017-09-01 15:02:45

标签: java inheritance override

我获得了一个名为帐户的超类,其中包含用于初始化余额的构造函数,以及存入和取消余额的方法,余额被声明为私有。 (我无法在此类中添加或更改任何方法或变量

然后,我创建了一个名为 SavingsAccount 的子类,其中包含一个接受初始余额的构造函数。如果初始余额为负数,那么该账户应该以余额0进行初始化。此外,它还包含两种过度使用的方法,存款和取款,用于检查存入和取出的金额,以查看是否可能。这是我提供的代码(帐户)和我写的(SavingsAccount)。

我尝试在if-else条件中调用super(),但是Java给出了一个错误,即super()调用必须是构造函数的第一行。那么,我该如何解决这个问题呢?另外,由于我在提供的Account类中没有setBalance()方法,如何在SavingsAccount类中设置存款和取款方法的余额?

Account.Java(提供测试,无法修改)

public class Account 
{
  private double balance;

    // Constructor to initialise balance
    public Account( double amount )
    {
            balance = amount;
    }

    // Overloaded constructor for empty balance
    public Account()
    {
            this(0.0);
    }

    public void deposit( double amount )
    {
            balance += amount;
    }

    public void withdraw( double amount )
    {
            balance -= amount;
     }

    public double getBalance()
    {
            return balance;
    }
}  

SavingsAccount.java(由我撰写)

public class SavingsAccount extends Account
{
   private int overDraftCount = 0;
   public SafeAccount(double initial_balance)
   {
      if(initial_balance <0)
      {
       super(0.00);
      }
      else
      {
       super(initial_balance);
      }
    }

   @Override
   public void deposit(double amount)
   {
    if(amount < 0)
   {
      ??? = getBalance(); 
   }
    else
   {
      ??? = getBalance()+ amount;
   }
  }
  @Override
  public void withdraw(double amount)
  {
    if(amount < getBalance())
    {
     overDraftCount++;
     ??? = getBalance();
    }

    else
    {
      ??? = getBalance() - amount;
     }
   }

  public int overdraftAttempts()
  {
     return overDraftCount;
  }
 }

4 个答案:

答案 0 :(得分:4)

您可以更改构造函数以使用三元运算符:

public SafeAccount(double initial_balance) {
  super(initial_balance < 0 ? 0.00 : initial_balance);
}

关于你的第二点,你将不得不使用现有方法从帐户中提取或存入储蓄,如下所示:

@Override
public void deposit(double amount) {
  if(amount > 0) {
    super.deposit(amount);
  }
}

答案 1 :(得分:2)

在这种情况下,可以使用

简单地解决
public SafeAccount(double initialBalance) {
    super(initialBalance < 0 ? 0.0 : initialBalance));
}

您还可以调用静态方法返回正确的初始余额。或者您可以使用工厂方法而不是构造函数:

private SafeAccount(double initialBalance) {
    super(initialBalance);
}

public static SafeAccount createSafeAccount(double initialBalance) {
    if (initialBalance < 0) {
        return new SafeAccount(0.0);
    }
    else {
        return new SafeAccount(initialBalance);
    }
}

请注意,忽略参数值的方式大部分时间都是个坏主意。传递负的初始余额并没有意义,因此是错误的标志。因此,它应该通过抛出异常来发出信号,而不是将其转换为0.0并隐藏错误,从而可能导致新的错误,甚至更加难以诊断。

关于你的第二个问题,我不知道问题出在哪里。您只需要委托超级方法:

@Override
public void deposit(double amount) {
    if (amount < 0) {
        throw new IllegalArgumentException("amount should be positive");
    }
    else {
        super.deposit(amount);
    }
}

答案 2 :(得分:1)

如果我理解正确,您想创建一个不能为负的帐户。

因此对于构造函数,您只需使用三元运算符:

    public SafeAccount(double initialBalance) {
        super(initialBalance < 0 ? 0 : initialBalance);
    }

对于存款/取款,您也可以使用Account来调用super的方法:

    @Override
    public void deposit(double amount) {
        if (amount > 0) {
            super.deposit(amount);
        }
    }

    @Override
    public void withdraw(double amount) {
        if (amount > getBalance()) {
            overDraftCount++;
            // if you want to set to 0.00
            super.withdraw(getBalance());
        } else {
            super.withdraw(amount);
        }
    }

所以,你的最后一堂课应该是这样的:

public class SafeAccount extends Account {

    private int overDraftCount = 0;

    public SafeAccount(double initialBalance) {
        super(initialBalance < 0 ? 0 : initialBalance);
    }

    @Override
    public void deposit(double amount) {
        if (amount > 0) {
            super.deposit(amount);
        }
    }

    @Override
    public void withdraw(double amount) {
        if (amount > getBalance()) {
            overDraftCount++;
            // if you want to set to 0.00
            super.withdraw(getBalance());
        } else {
            super.withdraw(amount);
        }
    }

    public int overdraftAttempts() {
        return overDraftCount;
    }
}

注意:您的代码不遵守Java代码约定,也许您应该看看它们(google java code conventions,你会发现)。

答案 3 :(得分:1)

您的SavingsAccount构造函数无法正常工作,因为您自己的构造函数的第一行必须是超级调用,否则您将收到编译错误。您可以通过以下方式获得所需的结果:

public SavingsAccount(double initial_balance) {
    super(getAdjustedInitialBalance(initial_balance));
}

private static double getAdjustedInitialBalance(double val) {
    return val < 0 ? 0 : val;
}

当然,三元运算符可以作为参数直接放在超级调用中,但我发现自己的方式更具可读性,因为它通过有意义的方法名来解释逻辑。

在负值的情况下,其他方法可以互相调用:

public void withdraw(double amount) {
    if (amount < 0) {
        deposit(-amount);
        return;
    }
    if (amount < getBalance()) {
        overDraftCount++;
        return;
    }
    super.withdraw(amount);
}

public void deposit(double amount) {
    if (amount < 0) {
        withdraw(-amount);
        return;
    }
    super.deposit(amount);
}

所以,你原来问题的答案是&#34;你不能&#34;#34; (从技术上讲,有一种方法,但你不要这样做,直到你真的需要,所以我不会告诉你;-)&#34;你不应该&#34;。您可以使用公开的方法并调用它们。

希望有助于你的作业(至少它看起来像一个)