300 likes | 473 Views
Java Programming(Part 3) Object-Oriented Programming. 鄧姚文 http://w3.im.knu.edu.tw/~joseph/ joseph@im.knu.edu.tw. 內容大綱. 物件與類別 資料成員 Methods 繼承 介面 物件型態轉換 範例程式. 物件與類別. 物件( Object) 一個完整的個體 包含資料( Data Member,Property,Instance Variable) 包含處理資料所需的方法( Method) 封裝( Encapsulation)
E N D
Java Programming(Part 3)Object-Oriented Programming 鄧姚文 http://w3.im.knu.edu.tw/~joseph/ joseph@im.knu.edu.tw
內容大綱 • 物件與類別 • 資料成員 • Methods • 繼承 • 介面 • 物件型態轉換 • 範例程式
物件與類別 • 物件(Object) • 一個完整的個體 • 包含資料(Data Member,Property,Instance Variable) • 包含處理資料所需的方法(Method) • 封裝(Encapsulation) • 對外提供一致的介面 • 隱藏內部細節(Information Hiding) • 類別(Class) • 物件的定義 • 套件(Package) • 相關類別的集合
物件與類別 Integer s = new Integer("321"); Integer n = new Integer(100); s 類別 物件 Integer 321 n m Integer 100 Integer m = n;
物件與類別:資料成員 (Data Member) • 修飾詞 • 存取權限 • public:可供外部存取 • protected:只供內部存取,但衍生類別亦可存取 • private:只供內部存取 • final:不可更改內容(常數) • static:Class Variable,相同類別的所有物件共用一份資料 • 資料型態: • Primitive type • Class
public class BlackHouse { private static Blueprint bp = new Blueprint(1); // 設計圖 public NumberPlate np; // 門牌 protected Fireplace fp; // 壁爐 } public class GrayHouse extends BlackHouse { private static Blueprint bp = new Blueprint(2); // 設計圖 // 自動有一個門牌 // 自動有一個壁爐 } … BlackHouse bh1 = new BlackHouse(); BlackHouse bh2 = new BlackHouse(); // bh1 和 bh2 的設計圖是同一份 // bh1 和 bh2 各有一個門牌
範例:存取權限、Package package com.shinewave.erp; import java.util.Hashtable; import java.awt.*; // wildcard but no recursive import java.awt.font.TextAttribute; import java.awt.color.*; import com.shinewave.bank.*; public class AccountTest { SavingsAccount momsSavings; // package access public TimeDepositAccount collegeFund; private CheckingAccount harrysChecking; ... }
物件與類別:Method • 修飾詞 • 存取權限 public、protected、private • static:相同類別的所有物件共用一份 • abstract:只定義 signature 不提供實作,強迫衍生類別實作 • Return type: primitive type、Class、void • 參數傳遞: • Primitive types: call by value • Class: call by reference • Signature: method name + parameter types
Primitive Types: call by value; Objects: call by reference import java.util.Hashtable; public class Calls { public Calls(int data, String str, Hashtable ht) { data += 100; str += " modified ?"; int v = ((Integer)ht.get("key1")).intValue() + 200; ht.put("key1", new Integer(v)); } public static void main(String[] args) { String strObject = "String object"; int iData = 100; Hashtable ht = new Hashtable(); ht.put("key1", new Integer(iData)); Calls cc = new Calls(iData, strObject, ht); System.out.println("iData = " + iData); System.out.println("strObject = " + strObject); System.out.println("ht(key1) = "+ ((Integer)ht.get("key1")).toString()); } }
範例:Method Signature、Overloading、Abstract method public class BasicAccountManager { public void endOfMonth(SavingsAccount savings) { savings.addInterest(); } public void endOfMonth(CheckingAccount checking) { checking.deductFees(); } // must override this one public abstract void printBalance(Account account); }
物件與類別:建構子(Constructor) • A constructor is a special method • Constructor 的 method name 必須與 class name 相同(包括大小寫) • Constructor 沒有傳回值,也不必標示傳回值資料型態(連 void 都不必寫) • Constructor 必須是 public • 一個 class 可以有多個 constructor,但必須每一個 constructor 的 method signature 都不相同(Overloading)
public class Sum1 { private int n; public Sum1() { this.n = 10; } public Sum1(String N) { this.n = Integer.parseInt(N); } public void print() { ... } public static void main(String[] args) { Sum1 sum = (args.length == 1) ? new Sum1(args[0]) : new Sum1(); sum.print(); } }
繼承(Inheritance) • The “is-a” relationship between a more general superclass and a more specialized subclass • A savings account is a bank account • A checking account is a bank account • A time deposit account is a savings account • super:the superclass • this:this class
BankAccount getBalance deposit withdraw SavingsAccount CheckingAccount addInterest deductFees deposit withdraw TimeDepositAccount addInterestwithdraw
public class BankAccount { public BankAccount() { balance = 0; } public BankAccount(double initialBalance) { balance = initialBalance; } public void deposit(double amount) { balance = balance + amount; } public void withdraw(double amount) { balance = balance - amount; } public double getBalance() { return balance; } public void transfer(BankAccount other, double amount) { withdraw(amount); other.deposit(amount); } private double balance; }
public class SavingsAccount extends BankAccount { public SavingsAccount(double rate) { interestRate = rate; } public void addInterest() { double interest = getBalance() * interestRate / 100; deposit(interest); } private double interestRate; }
public class CheckingAccount extends BankAccount { public CheckingAccount(int initialBalance) { // construct superclass super(initialBalance); // initialize transaction count transactionCount = 0; } public void deposit(double amount) { transactionCount++; // now add amount to balance super.deposit(amount); } public void withdraw(double amount) { transactionCount++; // now subtract amount from balance super.withdraw(amount); } public void deductFees() { if (transactionCount > FREE_TRANSACTIONS) { double fees = TRANSACTION_FEE * (transactionCount - FREE_TRANSACTIONS); super.withdraw(fees); } transactionCount = 0; } private int transactionCount; private static final int FREE_TRANSACTIONS = 3; private static final double TRANSACTION_FEE = 2.0; }
public class TimeDepositAccount extends SavingsAccount { public TimeDepositAccount(double rate, int maturity) { super(rate); periodsToMaturity = maturity; } public void addInterest() { periodsToMaturity--; super.addInterest(); } public void withdraw(double amount) { if (periodsToMaturity > 0) super.withdraw(EARLY_WITHDRAWAL_PENALTY); super.withdraw(amount); } private int periodsToMaturity; private static double EARLY_WITHDRAWAL_PENALTY = 20; }
public class AccountTest { public static void main(String[] args) { SavingsAccount momsSavings = new SavingsAccount(0.5); TimeDepositAccount collegeFund = new TimeDepositAccount(1, 3); CheckingAccount harrysChecking = new CheckingAccount(0); momsSavings.deposit(10000); collegeFund.deposit(10000); momsSavings.transfer(harrysChecking, 2000); collegeFund.transfer(harrysChecking, 980); harrysChecking.withdraw(500); harrysChecking.withdraw(80); harrysChecking.withdraw(400); endOfMonth(momsSavings); endOfMonth(collegeFund); endOfMonth(harrysChecking); printBalance("mom's savings", momsSavings); printBalance("the college fund", collegeFund); printBalance("Harry's checking", harrysChecking); } public static void endOfMonth(SavingsAccount savings) { savings.addInterest(); } public static void endOfMonth(CheckingAccount checking) { checking.deductFees(); } public static void printBalance(String name, BankAccount account) { System.out.println("The balance of "+name+ " account is $"+account.getBalance()); } }
介面(Interface) • A specialized view of an object • An interface does not have instance variables • Only constants • Automatic public static final • All methods in an interface are abstract • All methods in an interface are automatically public
範例:interface package com.shinewave.bank; public interface Account { String DOLLAR_SIGN = "$"; String printBalance(String accountName); }
package com.shinewave.bank; public class SavingsAccount extends BankAccount implements Account { public SavingsAccount(double rate) { interestRate = rate; } public void addInterest() { double interest = getBalance() * interestRate / 100; deposit(interest); } public String printBalance(String name) { String s = "The balance of " + name + " saving account is " + DOLLAR_SIGN + this.getBalance(); return s; } private double interestRate; }
package com.shinewave.bank; public class CheckingAccount extends BankAccount implements Account { public CheckingAccount(int initialBalance) { // construct superclass super(initialBalance); // initialize transaction count transactionCount = 0; } … public String printBalance(String name) { String s = "The balance of " + name + " checking account is " + DOLLAR_SIGN + this.getBalance(); return s; } … }
package com.shinewave.bank; public class TimeDepositAccount extends SavingsAccount implements Account { public TimeDepositAccount(double rate, int maturity) { super(rate); periodsToMaturity = maturity; } … public String printBalance(String name) { String s = "The balance of " + name + " time deposit account is " + DOLLAR_SIGN + this.getBalance(); return s; } … }
SavingsAccount sa = new SavingsAccount(); CheckingAccount ca = new CheckingAccount(); TimeDepositAccount tda = new TimeDepositAccount(); ... Account a1 = (Account)sa; Account a2 = (Account)ca; Account a3 = (Account)tda; ... a1.printBalance(); a2.printBalance(); a3.printBalance(); .... printBalance() printBalance() getBalance() printBalance() BankAccount SavingsAccount CheckingAccount TimeDepositAccount
物件型態轉換 • 可以將 subclass 物件轉換成 superclass 物件使用 • 將 superclass 物件轉換成 subclass 物件使用時要小心!
範例:轉型 int iData = 100; Integer iObj = new Integer(iData); Hashtable ht = new Hashtable(); ht.put("key1", iObj); // convert Integer to Object ... Integer iObj2 = (Integer)ht.get("key1"); int iData2 = iObj2.intValue() + 200; ...
Polymorphism • Selecting a method among several methods that have the same name on the basis of the actual types of the implicit parameters • 實際上被執行的 method 是該物件真實類別所實作的 method
SavingsAccount sa = new SavingsAccount(); CheckingAccount ca = new CheckingAccount(); TimeDepositAccount tda = new TimeDepositAccount(); ... AccountReport ba1 = (AccountReport)sa; AccountReport ba2 = (AccountReport)ca; AccountReport ba3 = (AccountReport)tda; ... ba1.printBalance(); ba2.printBalance(); ba3.printBalance(); .... printBalance() printBalance() getBalance() printBalance() BankAccount SavingsAccount CheckingAccount TimeDepositAccount