繁体   English   中英

如何使用多个构造函数创建对象?

[英]How do I create objects using more than one constructor?

我编写了以下代码和驱动程序,但不确定如何使用这两个构造函数创建银行帐户对象。 一个构造函数获得初始余额,而第二个构造函数则没有资金开设一个帐户。 另外,accountBalance是否应包括有效性检查?

(可选)我可以执行以下操作:

在描述银行帐户的内容中包括费用。 根据需要更新BankAccount类。 用户应该能够设置每个帐户的费用金额,并通过一种方法添加费用。 将代码添加到驱动程序中以演示收费功能。 (有人可以向我解释这是在问什么)

//Bank Account class   
import java.text.NumberFormat;

public class BankAccount {

private String ownerName;
private String accountId;
private double accountBalance;

public BankAccount(String ownerName, String accountId, double accountBalance) {
    this.ownerName = ownerName;
    this.accountId = accountId;
    if(accountBalance >= 0) { 
        this.accountBalance = accountBalance;           
    } else {
        System.out.println("Due to your negative account balace, you will be issued a fee.\n");
    }
}

public BankAccount(double accountBalance) {
    accountBalance = 0;
}

public String getOwnerName() {
    return ownerName;
}

public void setOwnerName(String ownerName) {
    this.ownerName = ownerName;
}

public String getAccountId() {
    return accountId;
}

public void setAccountId(String accountId) {
    this.accountId = accountId;
}

public double getAccountBalance() {
    return accountBalance;
}

public void setAccountBalance(double accountBalance) {
    if(accountBalance >= 0) { 
        this.accountBalance = accountBalance;           
    } else {
        System.out.println("Due to your negative account balace, you will be issued a fee.\n");
    }
}

public void withdraw(double amount) { 
    if(amount > 0 && amount < accountBalance) { 
        accountBalance -= amount;           
    } else {
        System.out.println("Invalid withdraw amount! Please try again.\n");
    }
}

public void deposit(double amount) { 
    if(amount > 0) { 
        accountBalance += amount;
    } else {
        System.out.println("Invalid deposit amount! Please try again.\n");
    }
}

public String toString() { 
    NumberFormat currencyFormatter = NumberFormat.getCurrencyInstance();
    return "Account Owner's Name: " + ownerName + "\n" + "Account ID: " + accountId + "\n" + 
           "Balance in the account: " + currencyFormatter.format(accountBalance);
}
}

//Driver Program
public class BankAccountDriver {

public static void main(String[] args) {

    BankAccount myAccount = new BankAccount("Smith", "123jahgsd", 1200);                      
    myAccount.withdraw(0.453);
    myAccount.deposit(1000.1);
    System.out.println(myAccount);
}
}

所有的答案都很不错,但实际上却“错过了”“真实的”问题; 那就是:您不必放下构造函数,因为可以

您创建满足您的要求所需的代码。 换句话说:您退后一步; 您会考虑为银行帐户类别设计 “预期用例”。

这里要考虑的事情: 避免使用可以使用这种不同路径创建的类。

例如:允许空的 ID /所有者字段非常危险。 这使这些字段具有null值; 这意味着您要么需要在这里和那里进行大量检查; 如果您忘记了这里或那里的话; 您迟早(而不是很快)会遇到NullPointerExceptions。

请记住:您的对象是用来表示 (模型!)“现实”的。 实际上,银行账户并非没有所有者。 或ID。

从这个意义上讲,您的类的明智实现将更像是:

public class BankAccount {
  private final String owner;
  private final String id;
  private double currentBalance;

  public BankAccount(String owner, String id) {
    this(ownwer, id, 0);
  }

  public BankAccount(String owner, String id, double currentBalance) {
    this.owner = owner;
    ...

注意事项:

  • 您想防止所有者/标识被更改,因此使它们成为最终的; 因此您也没有针对这些字段的设置方法
  • 在实际的解决方案中,您不会使用字符串来表示名称或ID,而是使用不同的类
  • 您也永远不会使用double来代表货币 这是一件很基本的事情: 金钱不应该使用浮点数表示! (您可能希望使用BigDecimal类;或者只是使用int而不是double(并且表示1.75 $为175美分)
  • 这只是现实世界的一瞥:如今,您并没有为银行帐户建模以拥有“经常余额”。 取而代之的是,银行帐户可能隶属于事件历史记录 (表示存款和支付交易)。

最后一点:对于您当前的练习,提款/存款的这种“验证”是“可以的”; 在“现实世界”中,验证也可能会在许多其他地方进行。 (回到我的最初声明:这一切都取决于您的模型;一个简单的模型可能会说一个银行帐户本身正在“验证”事物;但是更现实的解决方案是您还有其他处理“规则”的组件,“法律”和执行“验证”的各种主题)。

您可以根据要使用的构造函数来创建对象。 例如,要使用第一个构造函数,您需要像这样的三个参数,

BankAccount first = new BankAccount("Bob", "ID45", 400.50);

要使用第二个构造函数,您只需要一个参数,即balance,就像这样,

BankAccount second = new BankAccount(400.50);

他们都将创建BankAccount实例,除了不同之处在于,在创建时,第一个银行帐户将填充ownerNameaccountId字段,而第二个银行帐户会将这些字段设置为空String值。 但是,第二个对象的余额为0,与第一个对象的余额400.5不同

编辑:像用户ScaryWombat所建议的那样,第二个构造函数中也存在缺陷,因为如果您要定义一个余额为0的对象,那么添加balance参数毫无意义。 另外,在这种情况下,建议您也为其他字段提供默认值,

public BankAccount() {
    ownerName = "unknown";
    accountId = "unknown";
    accountBalance = 0;
}

因此,现在当您使用此构造函数创建BankAccount实例时,它将具有默认值“未知”,“未知”和0。

BankAccount third = new BankAccount();

另外,对于fee部分,您要做的不仅是在BankAccount类中创建另一个称为“ fee字段,还需要使用setter方法来允许用户设置费用,

private double fee;
.
.
.
public void setFee (double fee) {
   this.fee = fee;
}

在main方法中,用户可以通过以下方式进行访问:

BankAccount account = new BankAccount("Fred", "ID145", 400);
account.setFee(15); //this will set the fee to 15

您可以这样:

   public BankAccount(String ownerName, String accountId, double accountBalance) {
       this.ownerName = ownerName;
       this.accountId = accountId;
       this.accountBalance = accountBalance;
   }

   public BankAccount() {
       this("some default name", "some default id", 0.0);
   }

如果要创建零余额的BankAccount,则

public BankAccount(String ownerName, String accountId, double accountBalance) {
    this.ownerName = ownerName;
    this.accountId = accountId;
    this.accountBalance = accountBalance;
}

public BankAccount() {
    this.accountBalance = 0;
}

您可以将它们实例化为

BankAccount mine = new BankAccount("Scary", "123", 1000000.00);
BankAccount empty = new BankAccount();

编辑

如果选择使用第二种方法构造方法,则idowner也将为null ,可能不太有用

您不能同时使用两个构造函数来创建一个银行帐户对象。 您只需调用两个构造函数之一来创建一个新对象。 所以你要么做:

BankAccount account = new BankAccount("Sweeper", "ABCDEF", 10000);

要么:

BankAccount account = new BankAccount(100000);

请注意,第二个构造函数的参数是没有意义的,因为无论参数是什么,都将余额初始化为0:

public BankAccount(double accountBalance) {
    accountBalance = 0;
}

我认为这更有意义:

public BankAccount() {
    this.accountBalance = 0;
}

关于第二个问题,我将给您一些提示。

您需要在类中添加一个名为fee的新字段。 为此添加getter和setter。

暂无
暂无

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

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