2015-09-22 64 views
0

Goodrich和Tamassia的「數據結構和算法」一直困擾着我。這本書提出了以下兩類:java中私有成員變量的子類訪問

public class CreditCard { 
private String customer; 
private String bank; 
private String account; 
private int limit; 
protected double balance; 

public CreditCard(String customer, String bank, String account, int limit, double balance) { 
    this.customer = customer; 
    this.bank = bank; 
    this.account = account; 
    this.limit = limit; 
    this.balance = balance; 

} 

public CreditCard(String customer, String bank, String account, int limit) { 
    this(customer, bank, account, limit, 0.0); 
} 

public String getCustomer() { return this.customer; } 
public String getBank() { return this.bank; } 
public String getAccount() { return this.account; } 
public int getLimit() { return this.limit; } 
public double getBalance() { return this.balance; } 

public boolean charge(double price) { 
    if(price + this.balance > this.limit) 
     return false; 

    this.balance += price; 
    return true; 
} 

public void makePayment(double amount) { 
    if(amount < 0) 
     System.out.println("Cannot process negative payment"); 
    else 
     this.balance -= amount; 
} 

public void updateCreditLimit() { 
    this.limit -= balance; 
} 

public static void printSummary(CreditCard card) { 
    System.out.println("Customer = " + card.customer); 
    System.out.println("Bank = " + card.bank); 
    System.out.println("Account = " + card.account); 
    System.out.println("Balance = " + card.balance); 
    System.out.println("Limit = " + card.limit); 
} 

}

子類

public class PredatoryCreditCard extends CreditCard { 
private double apr; 

public PredatoryCreditCard(String customer, String bank, String account, 
          int limit, double balance, double apr) { 
           super(customer, bank, account, limit, balance); 
           this.apr = apr; 
          } 

public void processMonth() { 
    if(this.balance > 0) { 
     double monthlyFactor = Math.pow(1 + apr, 1F/12); 
     this.balance *= monthlyFactor; 
    } 
} 

public boolean charge(double price) { 
    boolean isSuccess = super.charge(price); 
    if(!isSuccess) 
     this.balance += 5; 
    return isSuccess; 
} 

} 

問:

假設我們改變的CreditCard類,以便實例變量balance具有私有可見。爲什麼PredatoryCreditCard.charge方法的以下兩種實現有缺陷?

public boolean charge(double price) { 
    boolean isSuccess = super.charge(price); 
    if(!isSuccess) 
     charge(5); //penalty for late fee 
    return isSuccess; 
} 

第二個:

public boolean charge(double price) { 
    boolean isSuccess = super.charge(price); 
    if(!isSuccess) 
     super.charge(5); //penalty for late fee 
    return isSuccess; 
} 

我的理解是,一個子類不能直接操作私有字段的是超一流的。該字段必須受到保護或公開。這允許我們在子類this.balance += 5中說。我對這些原則的理解不是問題,我的問題是我被要求回答的問題。從實施的角度來看,我無法在PredatoryCreditCard.charge方法中清楚地看到這個問題,因爲在這個問題提供的新實施的兩種情況下,我們正在改變班級的平衡領域,無論是因爲呼籲超。除非我認爲我的繼承知識存在漏洞,否則我無法在新實現中找到缺陷。

預先感謝您。

+0

如果5>限制 - 餘額不會在您的版本中發生變化。在版本中平衡屬性是直接操縱的,所以它增加了5個獨立的限制值和平衡值。 –

+1

而第一個替代可以導致無限遞歸。 –

回答

1

在任何一種情況下,如果您足夠接近餘額(價值5)的費用將超出您的限額,您將無法收取費用。在第一種情況下:

public boolean charge(double price) { 
    boolean isSuccess = super.charge(price); 
    if(!isSuccess) 
     charge(5); //penalty for late fee 
    return isSuccess; 
} 

isSuccess失敗時會發生什麼?我們陷入無限遞歸調用this.charge(...)

1

這兩種實現都沒有語法錯誤。兩者都有(或可能有)邏輯錯誤。

首次執行

public boolean charge(double price) { 
    boolean isSuccess = super.charge(price); 
    if(!isSuccess) 
     charge(5); //penalty for late fee 
    return isSuccess; 
} 

我們開始一個級別深度。

第一條語句是super.charge(price)
如果該聲明返回false,則我們致電this.charge(5)
我們現在是兩個層次。

第一條語句是super.charge(5)
如果該聲明返回false,則我們致電this.charge(5)
我們現在三層深。

第一條語句是super.charge(5)
如果該聲明返回false,則我們致電this.charge(5)
我們現在是四個層次。
...

你明白了吧。第一個實現會導致無限遞歸,然後會導致堆棧溢出。見What methods are there to avoid a stack overflow in a recursive algorithm?

第二實例

public boolean charge(double price) { 
    boolean isSuccess = super.charge(price); 
    if(!isSuccess) 
     super.charge(5); //penalty for late fee 
    return isSuccess; 
} 

我們試圖充電price。我們記錄交易是否成功。
如果交易失敗,我們會收取滯納金。我們不記錄交易是否成功。
如果延遲收費失敗,我們不在乎。

我不確定這裏的錯誤是什麼。它當然不模仿我的銀行如何工作,但這不一定是問題。我認爲避免滯納金是一件壞事,但這取決於你的要求。