簡體   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