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

问题描述:

我提供了一个名为账户的超类,其中包含构造函数用于初始化余额以及存款和提取余额的方法,并将余额声明为私有。 (我不能添加或更改在所有在这个类中的任何方法或变量)如何在不使用setter的情况下从子类访问父类中的私有字段?

然后,我创建了一个名为SavingsAccount与接受初始余额构造子类。如果初始余额为负数,那么帐户应以0的​​余额进行初始化。此外,它还包含两种叠加的方法,存款和取款,它们检查存入和取出的金额以查看是否可能。以下是我提供的代码(Account)和我写的(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; 
    } 
} 
+0

*所以,我怎么解决这个得到什么?*你不知道。 *另外,由于我没有在提供的Account类中使用setBalance()方法,因此我如何在SavingsAccount类中从我的存款和取款方法中设置余额?*您不能。子类不能访问他们父母的私人成员(至少不是没有反思,这不是一个好主意)。你为什么不能修改'Account'? –

+0

那么,它是由我的教师提供给我的,我将不得不根据提供的类(Account)创建子类,而不对提供的类进行任何更改。 – cfreq744

你可以改变你的构造函数,使用三元运算:

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

在这种情况下,它可以简单地使用

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

啊......这完全有道理!谢谢! – cfreq744

如果我正确理解,你想要一个帐户,不能是负面的。

所以对于构造函数,你只需要使用一个三元操作符:

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)。

+0

真棒...谢谢你的解释..一个快速的问题..我是超新的Java ..你可以解释(initialBalance cfreq744

+0

Nevermind ..明白了......查找三元操作 – cfreq744

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

所以,回答你原来的问题是“你不能”(以及技术上有一种方法,但你不直到你真的必须这样做,所以我不会把它展示给你;-)“你不应该”。您可以使用公开可用的方法并调用它们。

希望能与您的家庭作业帮助(至少它看起来像一个)