Records (Java 16+)
חלק מהיחידה תכנות מונחה עצמים במסלול ה-Java של Coddy. שיעור 51 מתוך 87.
בעת יצירת מחלקות פשוטות שנושאות נתונים, לעיתים קרובות כותבים קוד תשתיתי שחוזר על עצמו: שדות פרטיים, בנאי, מתודות גישה, toString(), equals() ו-hashCode(). ב-Java 16 הוצגו רשומות כדי לבטל את העבודה המייגעת הזאת.
רשומה היא מחלקה מיוחדת שנועדה להכיל נתונים בלתי־ניתנים לשינוי. מכריזים עליה באמצעות מילת המפתח record ולאחריה רשימת הרכיבים:
record Person(String name, int age) { }
// השורה היחידה הזו מספקת אוטומטית:
// - שדות private final: name ו-age
// - בנאי: Person(String name, int age)
// - מתודות גישה: name() ו-age()
// - toString(), equals() ו-hashCode()השימוש ב-record פשוט:
Person p = new Person("Alice", 30);
System.out.println(p.name()); // Alice
System.out.println(p.age()); // 30
System.out.println(p); // Person[name=Alice, age=30]שימו לב שמתודות גישה אינן משתמשות בקידומת get: הן פשוט נקראות על שם השדות. רשומות הן באופן מרומז final, ולכן אי אפשר לרשת מהן. כל השדות הן גם final, ולכן רשומות הן בלתי ניתנות לשינוי מטבען.
אפשר להוסיף מתודות מותאמות אישית ולדרוס את אלה שנוצרו אוטומטית אם צריך. אפשר גם להוסיף אימות בבנאי קומפקטי:
record Person(String name, int age) {
public Person {
if (age < 0) throw new IllegalArgumentException("Age cannot be negative");
}
}רשומות מתאימות במיוחד לאובייקטי DTO, לתשובות API או לכל תרחיש שבו צריך מיכל נתונים פשוט ובלתי ניתן לשינוי, בלי לכתוב קוד תבניתי.
אתגר
קלבואו נבנה מערכת להזמנת כרטיסים לסרטים שמדגימה את האלגנטיות של רשומות ב-Java. תראו איך רשומות מבטלות קוד תבניתי, ובו בזמן מאפשרות להוסיף שיטות מותאמות אישית ואימות.
תארגנו את הקוד שלכם בשלושה קבצים:
Movie.java: צרו רשומה שמייצגת סרט עם שלושה רכיבים:title(String),genre(String) ו-durationMinutes(int). הוסיפו שיטה מותאמת אישית בשםgetFormattedDuration()שמחזירה את משך הזמן בפורמט ידידותי:[hours]h [minutes]m(לדוגמה, 142 דקות הופכות ל-2h 22m). השתמשו בחלוקה שלמה ובשארית כדי לחשב את מספר השעות ואת הדקות שנותרו.Ticket.java: צרו רשומה שמייצגת כרטיס לסרט עם שלושה רכיבים:movie(Movie),seatNumber(String) ו-price(double). הוסיפו בנאי קומפקטי שמאמת את המחיר: אם המחיר קטן או שווה לאפס, זרקוIllegalArgumentExceptionעם ההודעהPrice must be positive. הוסיפו גם שיטה מותאמת אישית בשםprintTicket()שמחזירה מחרוזת מרובת שורות:========== TICKET ========== Movie: [movie title] Genre: [movie genre] Duration: [formatted duration from movie] Seat: [seatNumber] Price: $[price] ============================Main.java: חברו את מערכת ההזמנות שלכם! תקבלו חמש קלטים: שם הסרט (String), ז'אנר (String), משך הזמן בדקות (int), מספר המושב (String) ומחיר הכרטיס (double).צרו רשומת Movie באמצעות שלושת הקלטים הראשונים, ואז צרו רשומת Ticket עם הסרט, מספר המושב והמחיר. הדפיסו את התוצאה של קריאה ל-
printTicket()בכרטיס שלכם.
תקבלו חמישה קלטים לפי הסדר: שם הסרט, ז'אנר, משך הזמן (בדקות), מספר המושב והמחיר.
שימו לב עד כמה רשומות נקיות יותר ממחלקות מסורתיות: אין צורך לכתוב בנאים, שיטות גישה, toString(), equals() או hashCode. הבנאי הקומפקטי מאפשר לכם להוסיף אימות בלי לחזור על השמות של השדות, ועדיין תוכלו להוסיף שיטות מותאמות אישית כשצריך!
נסו בעצמכם
import java.util.Scanner;
class Main {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
// קרא את הקלטים
String title = scanner.nextLine();
String genre = scanner.nextLine();
int durationMinutes = Integer.parseInt(scanner.nextLine());
String seatNumber = scanner.nextLine();
double price = Double.parseDouble(scanner.nextLine());
// TODO: צור רשומת Movie עם title, genre ו-durationMinutes
// TODO: צור רשומת Ticket עם הסרט, seatNumber והמחיר
// TODO: הדפס את הכרטיס באמצעות המתודה printTicket()
}
}
השיעור הזה כולל חידון קצר. התחילו את השיעור כדי לענות עליו ולעקוב אחרי ההתקדמות.
כל השיעורים ביחידה תכנות מונחה עצמים
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 אונליין