【问题标题】:How to access private fields in superclass from a subclass without using setters?如何在不使用 setter 的情况下从子类访问超类中的私有字段?
【发布时间】:2017-09-01 15:02:45
【问题描述】:

我已经获得了一个名为 Account 的超类,它带有用于初始化余额的构造函数,以及存款和提取余额的方法,余额被声明为私有。 (我根本无法在此类中添加或更改任何方法或变量

然后,我创建了一个名为 SavingsAccount 的子类,其中包含一个接受初始余额的构造函数。如果初始余额为负数,则该帐户应初始化为余额 0。此外,它包含两个覆盖的方法,存款和取款,用于检查存款和取款的金额,看是否可能。这是提供给我的代码(帐户)和我编写的代码(储蓄帐户)。

我尝试在 if-else 条件中调用 super(),但 Java 给出了一个错误,即 super()call 必须是构造函数的第一行。那么,我该如何解决呢?另外,由于我在提供的 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;
  }
 }

【问题讨论】:

  • 那么,我该如何解决这个问题? 你不知道。 另外,由于我在提供的 Account 类中没有 setBalance() 方法,我如何在我的 SavingsAccount 类中设置我的存款和取款方法的余额? 你不能。子类无法访问其父级的私有成员(至少不是没有反射,这不是一个好主意)。为什么不能修改Account
  • 嗯,它是我的导师提供给我的,我必须根据提供的类(帐户)创建子类,而不对提供的类进行任何更改。

标签: java inheritance overriding


【解决方案1】:

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

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);
  }
}

【讨论】:

    【解决方案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 并隐藏错误,这可能会导致新的错误,甚至更令人讨厌且更难诊断。

    关于你的第二个问题,我真的不明白问题出在哪里。你只需要委托给 super 方法:

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

    【讨论】:

    • 啊...这完全有道理!谢谢!
    【解决方案3】:

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

    所以对于构造函数,你只需要使用三元运算符:

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

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

        @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,您会发现)。

    【讨论】:

    • 太棒了...谢谢您的解释..一个快速的问题..我对 java 很陌生..你能解释一下 (initialBalance
    • 没关系.. 明白了...查了一下三元运算
    【解决方案4】:

    你的 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);
    }
    

    所以,你原来的问题的答案是“你不能”(从技术上讲,有一种方法,但在你真的必须这样做之前你不会这样做,所以我不会向你展示它;-) “你不应该”。您使用公开可用的方法并调用它们。

    希望对你的作业有所帮助(至少看起来像一个)

    【讨论】:

      猜你喜欢
      • 2015-06-02
      • 1970-01-01
      • 2015-10-07
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-09-05
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多