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為什麼有提供運算子過載的功能,也沒有給程式設計師自己過載運算子的權利,我覺得應該是為了精簡程式然後建立了特定的包為此服務吧。