שירות השכרת כלי רכב
חלק מהיחידה תכנות מונחה עצמים במסלול ה-Java של Coddy. שיעור 87 מתוך 87.
באתגר הסופי הזה תבנה מערכת השכרת כלי רכב המשלבת את כל מושגי התכנות מונחה העצמים (OOP) ששלטת בהם לאורך הקורס.
המערכת שלך צריכה למדל צי של סוגי כלי רכב שונים. כדאי לשקול מחלקת בסיס Vehicle עם מאפיינים משותפים כמו לוחית רישוי, מותג ותעריף השכרה יומי. מחלקות משנה כגון Car, Motorcycle ו-Truck יכולות להרחיב אותה באמצעות מאפיינים ספציפיים כמו מספר המושבים, נפח המנוע או קיבולת המטען.
ממשקים יכולים להגדיר התנהגויות להשכרה: ממשק Rentable עשוי להצהיר על מתודות כמו rent(), returnVehicle() ו־calculateCost(int days). סוגי כלי רכב שונים יכולים לממש אסטרטגיות תמחור בדרכים שונות, ולכן זהו מקרה שימוש מושלם לפולימורפיזם.
חשוב על האופן שבו מחלקת RentalAgency מנהלת את צי הרכב באמצעות קומפוזיציה.
חריגות מותאמות אישית כמו VehicleNotAvailableException יכולות לטפל במקרי קצה.
ייתכן שתיישם את תבנית המפעל כדי ליצור כלי רכב או להשתמש במונים עבור קטגוריות כלי רכב וסטטוס השכרה.
האתגר הזה בוחן את היכולת שלך לתכנן מערכת OOP שלמה ומובנית היטב. בהצלחה!
אתגר
קלבואו נבנה שירות השכרת כלי רכב מלא שמאגד את כל מה שלמדת על OOP! תיצור מערכת שמנהלת צי של סוגי כלי רכב שונים, מטפלת בהשכרות תוך אימות מתאים ומשתמשת בתבנית מפעל כדי ליצור כלי רכב.
תארגן את הקוד שלך בשבעה קבצים:
RentalStatus.java: צור enum שמייצג את מצב ההשכרה של כלי רכב. כלול את הערכיםAVAILABLE,RENTEDו-MAINTENANCE. הוסף שדה פרטיdescription(String), בנאי ומתודה לקבלת הערך. עבור AVAILABLE, התיאור צריך להיות "ready to rent", עבור RENTED התיאור צריך להיות "currently in use", ועבור MAINTENANCE התיאור צריך להיות "under service".VehicleNotAvailableException.java: צור חריגה מותאמת אישית שמרחיבה אתException. הבנאי צריך לקבל מספר לוחית רישוי וליצור הודעה בפורמטVehicle not available: [licensePlate].Rentable.java: צור ממשק שמגדיר פעולות השכרה. הכרז על המתודותrent()שמחזירה boolean,returnVehicle()שמחזירה boolean ו-calculateCost(int days)שמחזירה double.Vehicle.java: צור מחלקת בסיס מופשטת לכל כלי הרכב. כלול שדות פרטיים עבורlicensePlate(String),brand(String),dailyRate(double) ו-status(RentalStatus, מאותחל ל-AVAILABLE). הבנאי מקבל licensePlate, brand ו-dailyRate. כלול מתודות לקבלת הערכים המתאימות ומתודה להגדרת status. הכרז על מתודה מופשטתgetVehicleType()שמחזירה String. ממש את המתודהgetDetails()כך שתחזיר"[licensePlate] [brand] ([vehicleType]) - $[dailyRate]/day - [status description]", כאשר dailyRate מעוצב עם 2 ספרות אחרי הנקודה העשרונית.Car.java: צור מחלקה שמרחיבה את Vehicle ומממשת את Rentable. הוסף שדה פרטיseats(int). הבנאי מקבל licensePlate, brand, dailyRate ו-seats. ממש אתgetVehicleType()כך שתחזיר"Car". עבורrent(), אם המצב הוא AVAILABLE, הגדר אותו ל-RENTED והחזר true; אחרת החזר false. עבורreturnVehicle(), אם המצב הוא RENTED, הגדר אותו ל-AVAILABLE והחזר true; אחרת החזר false. עבורcalculateCost(int days), החזר את dailyRate כפול מספר הימים.Motorcycle.java: צור מחלקה שמרחיבה את Vehicle ומממשת את Rentable. הוסף שדה פרטיengineCC(int). הבנאי מקבל licensePlate, brand, dailyRate ו-engineCC. ממש אתgetVehicleType()כך שתחזיר"Motorcycle". ממש את המתודות של Rentable באותו אופן כמו ב-Car, אבלcalculateCost()צריכה להחיל הנחה של 10% (כפל ב-0.9).RentalAgency.java: צור מחלקה שמנהלת את צי כלי הרכב באמצעות ArrayList. כלול את המתודות הבאות:addVehicle(Vehicle vehicle)- מוסיפה כלי רכב לציfindVehicle(String licensePlate)- מחזירה את ה-Vehicle או nullrentVehicle(String licensePlate, int days)- מוצאת את כלי הרכב, מנסה להשכיר אותו (באמצעות המרה ל-Rentable) ומחזירה את עלות ההשכרה. זרוקVehicleNotAvailableExceptionאם כלי הרכב לא נמצא או אם rent() מחזירה falsereturnVehicle(String licensePlate)- מוצאת ומחזירה את כלי הרכב, ומחזירה true במקרה של הצלחהgetAvailableVehicles()- מחזירה ArrayList של כלי רכב שמצבם AVAILABLE
Main.java: בנה את שירות ההשכרה שלך! תקבל מחרוזת פקודות המופרדת בפסיקים:ADD_CAR:licensePlate:brand:dailyRate:seatsADD_MOTORCYCLE:licensePlate:brand:dailyRate:engineCCRENT:licensePlate:daysRETURN:licensePlateAVAILABLE
עבד כל פקודה והדפס:
- ADD_CAR/ADD_MOTORCYCLE:
Added: [brand] ([vehicleType]) - RENT:
Rented [licensePlate] for [days] days - Total: $[cost](עלות עם 2 ספרות אחרי הנקודה העשרונית), אוError: [exception message] - RETURN:
Returned: [licensePlate]אוReturn failed: [licensePlate] - AVAILABLE: הדפס את
Available vehicles:ולאחריו את הפרטים של כל כלי רכב זמין, כל אחד בשורה נפרדת
לאחר עיבוד כל הפקודות, הדפס את
--- Fleet Summary ---ולאחריו את הפרטים של כל כלי הרכב.
תקבל קלט אחד: מחרוזת הפקודות המופרדת בפסיקים.
לדוגמה, עבור הקלט ADD_CAR:ABC-123:Toyota:50.00:5,ADD_MOTORCYCLE:XYZ-789:Honda:40.00:600,RENT:ABC-123:3,RENT:ABC-123:2,AVAILABLE,RETURN:ABC-123, הפלט שלך יהיה:
Added: Toyota (Car)
Added: Honda (Motorcycle)
Rented ABC-123 for 3 days - Total: $150.00
Error: Vehicle not available: ABC-123
Available vehicles:
XYZ-789 Honda (Motorcycle) - $40.00/day - ready to rent
Returned: ABC-123
--- Fleet Summary ---
ABC-123 Toyota (Car) - $50.00/day - ready to rent
XYZ-789 Honda (Motorcycle) - $40.00/day - ready to rentהאתגר הזה משלב ירושה (ההיררכיה של Vehicle), ממשקים (Rentable), enums (RentalStatus), חריגות מותאמות אישית, פולימורפיזם (התייחסות אחידה לסוגים שונים של כלי רכב) והרכבה (RentalAgency מנהלת כלי רכב) למערכת שירות השכרה מלאה!
נסו בעצמכם
import java.util.Scanner;
import java.util.ArrayList;
class Main {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
String input = scanner.nextLine();
// TODO: צרו מופע של RentalAgency
// TODO: פצלו את הקלט לפי פסיקים כדי לקבל פקודות נפרדות
// TODO: עבדו כל פקודה:
// ADD_CAR:licensePlate:brand:dailyRate:seats -> הדפיסו "Added: [brand] ([vehicleType])"
// ADD_MOTORCYCLE:licensePlate:brand:dailyRate:engineCC -> הדפיסו "Added: [brand] ([vehicleType])"
// RENT:licensePlate:days -> הדפיסו "Rented [licensePlate] for [days] days - Total: $[cost]" (עם 2 ספרות אחרי הנקודה העשרונית)
// או "Error: [exception message]" אם נזרקת חריגה
// RETURN:licensePlate -> הדפיסו "Returned: [licensePlate]" או "Return failed: [licensePlate]"
// AVAILABLE -> הדפיסו "Available vehicles:" ולאחר מכן את פרטי כל רכב זמין
// TODO: אחרי כל הפקודות, הדפיסו "--- Fleet Summary ---"
// ולאחר מכן את פרטי כל רכב
}
}
השיעור הזה כולל חידון קצר. התחילו את השיעור כדי לענות עליו ולעקוב אחרי ההתקדמות.
כל השיעורים ביחידה תכנות מונחה עצמים
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 אונליין