1. 程式人生 > 實用技巧 >2020/10/27 Java學習記錄No.7

2020/10/27 Java學習記錄No.7

個人銀行賬戶管理系統技術總結

首先在class的建立過程中,C++習慣將private,public,protected的成員一起宣告,而java習慣在每一個成員前宣告其型別;然後對於類物件的建立,這一點兩種語言有比較大的差別。對於Java而言,產生物件的程式碼是

new SavingsAccount();

這句話的含義是:根據類模板產生一個物件,並在計算機記憶體中為此物件開闢一塊新的獨立記憶體空間,實質上是將類中定義的屬性複製到生成的物件中,為物件服務;開闢的新空間為棧空間,用於存放方法中的區域性變數和形式引數,並且方法在執行時還能訪問複製到物件中的屬性,當方法執行完畢後再釋放棧空間。而

SavingsAccount sa0;

這句程式碼雖然在C++中已經產生了一個物件,但在Java中只是產生了一個SavingsAccount的宣告而已,並沒有任何此類的物件產生,也沒有為其分配空間,而這時的sa0就好比一個遙控器,使用它則需要給它繫結一個物件

 SavingsAccount sa0 = new SavingsAccount(1, 21325302, 0.015);


在建立建構函式時,兩種語言對其的初始化也有不同,對比如下

    //建構函式 Java
    public SavingsAccount(int date, int id, double rate){
        
this.id = id; this.balance = 0; this.rate = rate; this.lastDate = date; this.accumulation = 0; System.out.println(date+"\t#"+id+"is created"); } //建構函式 C++ SavingsAccount::SavingsAccount(int date, int id, double rate) : id(id), balance(0), rate(rate), lastDate(date), accumulation(0
) {cout << date << "\t#" << id << " is created" << endl;}

在C++中兩種使用上述兩種方法初始化都是可以的。在Java中如果建構函式的第一條語句是一條普通的語句。也就是說,不是對this()或super()的呼叫,那麼java會插入一個隱式的super()呼叫,從而呼叫超類的預設建構函式。從該呼叫返回時,Java將對當前類的例項變數初始化,並繼續執行當前建構函式的語句。如果建構函式的第一條語句是通過super()對一個超類建構函式的呼叫,那麼Java則會呼叫所選定的超類建構函式。在其返回時,Java將對當前類的例項變數初始化,並繼續執行當前建構函式的語句。


在C++的class中,原始碼有許多地方是在類中定義方法,在類外實現

void record(int date, double amount);
.
..
...
void SavingsAccount::record(int date, double amount) {
    accumulation = accumulate(date);
    lastDate = date;
    amount = floor(amount * 100 + 0.5) / 100;    //保留小數點後兩位
    balance += amount;
    total += amount;
    cout << date << "\t#" << id << "\t" << amount << "\t" << balance << endl;
}

這樣的佈局可以使程式更加直觀,可以直接在類中看到有哪些方法;而Java中則不行,Java是完全面向物件的語言,所有函式和變數部必須是類的一部分。除了基本資料型別之外,其餘的都作為類物件,包括陣列。物件將資料和方法結合起來,把它們封裝在類中,這樣每個物件都可實現自己的特點和行為。從這一點可以體會到Java面對物件的思想,相比於C++有更好的封裝性。類似的Java可以把方法定義放在介面或抽象類中
具體實現用子類來做,

abstract class Account {
    private String id;
    private double balance;
    private static double total;
   .
   .
   .
   .
    abstract void deposit(Date date, double amount, String desc);
    abstract void withdraw(Date date, double amount, String desc);
    abstract void settle(Date date);

}
class CreditAccount extends Account{
    private Accumulator acc;    //輔助計算利息的累加器
    private double credit;        //信用額度
    private double rate;        //欠款的日利率
    private double fee;            //信用卡年費
   .
   .
   .
   .
    //存入現金
    public void deposit(Date date, double amount, String desc){
        record(date,amount,desc);
        acc.change(date,getDebt());
    }
    //取出現金
    public void withdraw(Date date, double amount,String desc){
        if (amount - getBalance() > credit) {
            error("not enough credit");
        } else {
            record(date, -amount, desc);
            acc.change(date, getDebt());
        }
    }
    //結算利息和年費,每月1日呼叫一次該函式
    public void settle(Date date){
        double interest = acc.getSum(date) * rate;
        if (interest != 0)
            record(date, interest, "interest");
        if (date.getMonth() == 1)
            record(date, -fee, "annual fee");
        acc.reset(date, getDebt());
    }
   .
   .
   .
}

C++支援多重繼承,這是C++的一個特徵,它允許多父類派生一個類。儘管多重繼承功能很強,但使用複雜,而且會引起許多麻煩,編譯程式實現它也很不容易。Java不支援多重繼承,但允許一個類繼承多個介面,實現了C++多重繼承的功能,又避免了C++中的多重繼承實現方式帶來的諸多不便。類似的,在Java中也沒有操作符過載,在老師上課中提到了一個比較特別的例子,String中的+號運算子,作用則是字串的拼接,只要其中一個數據的型別為String,+號都會起到這樣的作用。至於Java為什麼有提供運算子過載的功能,也沒有給程式設計師自己過載運算子的權利,我覺得應該是為了精簡程式然後建立了特定的包為此服務吧。