מערכת בנקאות
חלק מהיחידה תכנות מונחה עצמים במסלול ה-Java של Coddy. שיעור 85 מתוך 87.
באתגר הזה תבנה מערכת בנקאית שמדמה פעולות פיננסיות מהעולם האמיתי באמצעות עקרונות של תכנות מונחה עצמים.
המערכת שלך צריכה לטפל בסוגי חשבונות שונים כמו SavingsAccount ו-CheckingAccount, ששניהם יורשים ממחלקת הבסיס Account. לכל סוג חשבון יש התנהגויות ייחודיות: חשבונות חיסכון עשויים לצבור ריבית, בעוד שלחשבונות עו״ש עשויה להיות הגנה מפני משיכת יתר.
חשוב איך למדל עסקאות. ממשק כמו Transactable יכול להגדיר שיטות עבור deposit() ו־withdraw(). כדאי לשקול להשתמש בחריגות מותאמות אישית כגון InsufficientFundsException כדי לטפל בפעולות לא תקינות בצורה חלקה.
מחלקת Bank יכולה לנהל כמה חשבונות ולקוחות, ולהדגים הרכבה. אפשר ליישם את תבנית המפעל כדי ליצור סוגים שונים של חשבונות, או להשתמש בתבנית Observer כדי להודיע ללקוחות על שינויים בחשבון.
התמקדו בכימוס כדי להגן על נתונים רגישים כמו יתרות ומספרי חשבון, והשתמשו בפולימורפיזם כדי לעבד סוגי חשבונות שונים באופן אחיד.
אתגר
קלבואו נבנה מערכת בנקאית מלאה שמדגימה את השליטה שלך בעקרונות OOP! תיצור מערכת עם סוגי חשבונות שונים, טיפול בעסקאות וניהול חריגות תקין: הכול מאורגן בכמה קבצים.
תארגן את הקוד שלך בשבעה קבצים:
Transactable.java: צור ממשק שמגדיר את החוזה לפעולות פיננסיות. הוא צריך להצהיר על המתודותdeposit(double amount)ו-withdraw(double amount), כששתיהן מחזירות ערך בוליאני לציון הצלחה.InsufficientFundsException.java: צור חריגה מותאמת אישית שיורשת מ-Exception. הבנאי צריך לקבל את סכום המשיכה שנוסתה ואת היתרה הנוכחית, וליצור הודעה בפורמטInsufficient funds: attempted [amount], available [balance].Account.java: צור מחלקת בסיס מופשטת שמייצגת כל חשבון בנק. כלול שדות פרטיים עבורaccountNumber(String) ו-balance(double), בנאי שמאתחל את שניהם, פעולות getter מתאימות, פעולת setter מוגנת עבור היתרה (כדי שמחלקות יורשות יוכלו לשנות אותה), ומתודה מופשטתgetAccountType()שמחזירה String. ממש את המתודהgetDetails()כך שתחזיר"[accountNumber] ([accountType]): $[balance]", כאשר היתרה מעוצבת עם 2 ספרות אחרי הנקודה העשרונית.SavingsAccount.java: צור מחלקה שיורשת מ-Accountומממשת אתTransactable. הוסף שדה פרטי עבורinterestRate(double). הבנאי מקבל accountNumber, יתרה התחלתית ו-interestRate. ממש אתgetAccountType()כך שתחזיר"Savings". עבורdeposit(), הוסף את הסכום ליתרה והחזר true. עבורwithdraw(), אם הסכום גדול מהיתרה, החזר false; אחרת חסר אותו והחזר true. הוסף מתודהapplyInterest()שמגדילה את היתרה ב-balance * interestRate(השיעור נשמר כשבר, ולכן0.05פירושו 5%).CheckingAccount.java: צור מחלקה שיורשת מ-Accountומממשת אתTransactable. הוסף שדה פרטי עבורoverdraftLimit(double). הבנאי מקבל accountNumber, יתרה התחלתית ו-overdraftLimit. ממש אתgetAccountType()כך שתחזיר"Checking". עבורdeposit(), הוסף את הסכום והחזר true. עבורwithdraw(), אפשר משיכה אם הסכום קטן או שווה ליתרה בתוספת overdraftLimit; החזר false אם הוא חורג מהמגבלה.Bank.java: צור מחלקה שמנהלת חשבונות באמצעות ArrayList. כלול את המתודות:addAccount(Account account)- מוסיפה חשבון לבנקfindAccount(String accountNumber)- מחזירה את ה-Account או null אם לא נמצאtransfer(String fromAccount, String toAccount, double amount)- מעבירה כסף בין חשבונות, וזורקתInsufficientFundsExceptionאם אין מספיק כסף בחשבון המקור. במקרה של הצלחה, החזר"Transferred $[amount] from [fromAccount] to [toAccount]"getTotalDeposits()- מחזירה את סכום היתרות של כל החשבונות
Main.java: בנה את המערכת הבנקאית שלך! תקבל מחרוזת של פקודות המופרדות בפסיקים:SAVINGS:accountNumber:balance:interestRateCHECKING:accountNumber:balance:overdraftLimitDEPOSIT:accountNumber:amountWITHDRAW:accountNumber:amountTRANSFER:fromAccount:toAccount:amountINTEREST:accountNumber
עבד כל פקודה והדפס:
- SAVINGS/CHECKING:
Account created: [accountNumber] - DEPOSIT:
Deposited $[amount] to [accountNumber] - WITHDRAW:
Withdrew $[amount] from [accountNumber]במקרה של הצלחה, אוWithdrawal failed: [accountNumber] - TRANSFER: הדפס את הודעת ההצלחה או
Transfer failed: [exception message] - INTEREST:
Interest applied to [accountNumber]
לאחר כל הפקודות, הדפס
--- Bank Summary ---, ואחריו את הפרטים של כל חשבון (באמצעותgetDetails()), ולבסוף אתTotal deposits: $[total]בפורמט של 2 ספרות אחרי הנקודה העשרונית.
תקבל קלט אחד: מחרוזת הפקודות המופרדת בפסיקים.
לדוגמה, עבור הקלט SAVINGS:SAV001:1000.00:0.05,CHECKING:CHK001:500.00:200.00,DEPOSIT:SAV001:250.00,WITHDRAW:CHK001:600.00,TRANSFER:SAV001:CHK001:100.00,INTEREST:SAV001, הפלט שלך יהיה:
Account created: SAV001
Account created: CHK001
Deposited $250.00 to SAV001
Withdrew $600.00 from CHK001
Transferred $100.00 from SAV001 to CHK001
Interest applied to SAV001
--- Bank Summary ---
SAV001 (Savings): $1207.50
CHK001 (Checking): $0.00
Total deposits: $1207.50שים לב איך חשבון העו"ש מאפשר משיכה של $600 למרות שיש בו יתרה של $500 בלבד: כך פועלת הגנת משיכת היתר! חשבון החיסכון צובר ריבית של 5% על היתרה שלו לאחר ההעברה. האתגר הזה משלב ירושה, ממשקים, פולימורפיזם, חריגות מותאמות אישית וכימוס, לכדי יישום בנקאי מציאותי!
נסו בעצמכם
import java.util.Scanner;
class Main {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
String input = scanner.nextLine();
// TODO: צור מופע של Bank
// TODO: פצל את input לפי פסיקים כדי לקבל פקודות נפרדות
// TODO: עבד כל פקודה:
// - SAVINGS:accountNumber:balance:interestRate -> צור SavingsAccount, הדפס "Account created: [accountNumber]"
// - CHECKING:accountNumber:balance:overdraftLimit -> צור CheckingAccount, הדפס "Account created: [accountNumber]"
// - DEPOSIT:accountNumber:amount -> הפקד והדפס "Deposited $[amount] to [accountNumber]"
// - WITHDRAW:accountNumber:amount -> משוך והדפס הודעת הצלחה או "Withdrawal failed: [accountNumber]"
// - TRANSFER:fromAccount:toAccount:amount -> העבר והדפס הודעת הצלחה או "Transfer failed: [exception message]"
// - INTEREST:accountNumber -> החל ריבית והדפס "Interest applied to [accountNumber]"
// TODO: לאחר כל הפקודות, הדפס "--- Bank Summary ---"
// TODO: הדפס את פרטי כל חשבון באמצעות getDetails()
// TODO: הדפס "Total deposits: $[total]" בפורמט של 2 ספרות אחרי הנקודה העשרונית
}
}
השיעור הזה כולל חידון קצר. התחילו את השיעור כדי לענות עליו ולעקוב אחרי ההתקדמות.
כל השיעורים ביחידה תכנות מונחה עצמים
1יסודות התכנות מונחה העצמים
קבצים חיצונייםמבוא לתכנות מונחה עצמיםמחלקות לעומת אובייקטיםמילת המפתח thisמתודותשדות (מאפיינים)מתודת הבנאיהעמסת בנאיםחזרה – מחשבון פשוט4ירושה
ירושה בסיסית (extends)מילת המפתח superדריסת מתודות (@Override)שרשור בנאיםהמחלקה Objectירושה יחידה ורב־רמתיתלמה אין ירושה מרובה של מחלקותסיכום – היררכיית עובדים7מתודות מיוחדות ומחלקת Object
מתודת toString()equals() ו-hashCode()מתודת clone()compareTo() ו-Comparableהממשק Comparatorסיכום – מיון מותאם אישית2מצייני גישה ואנקפסולציה
סקירה של רמות הגישהמתודות Getter ו-Setterהסתרת מידעמילת המפתח finalסיכום – מנהל חשבון בנק5פולימורפיזם
יסודות העמסת מתודותדריסת מתודות (בזמן ריצה)המרה כלפי מעלה וכלפי מטההאופרטור instanceofמחלקות ומתודות מופשטותסיכום – מחשבון צורות8מושגי OOP מתקדמים
הרכבה מול ירושהאגרגציה מול הרכבהמחלקות פנימיות, מקוננות ואנונימיותEnums ומתודות של EnumRecords (Java 16+)מחלקות חתומות (Java 17+)3מאפייני מחלקה וחברים סטטיים
משתני מופע לעומת משתנים סטטייםמתודות סטטיותבלוקים סטטייםקבועים (static final)סיכום — מונה ומחלקת עזר6ממשקים ומחלקות מופשטות
מבוא לממשקיםמימוש ממשקיםמימוש של כמה ממשקיםמתודות ברירת מחדל וסטטיות בממשקמחלקות מופשטות לעומת ממשקיםממשקים פונקציונלייםסיכום – מערכת תשלומיםתרגלו בעצמכם: קומפיילר Java אונליין