Java וחשיבה מונחית עצמים
בני נוער

OOP ב-Java לנוער: מחלקות, ירושה ופולימורפיזם במשחק אחד

קוסם, רץ ורובוט מקבלים אותה פקודת תנועה — וכל אחד מגיב אחרת. דרך משחק קטן אפשר להבין למה תכנות מונחה עצמים הוא שיטת ארגון, לא אוסף מילים מסובכות.

עודכן: יולי 2026
כ-4 דקות קריאה
מחלקות, אובייקטים ותכנון קוד

במשחק קטן יש שלוש דמויות. הקוסם מחליק קדימה, הרץ מזנק שתי משבצות והרובוט מתקדם צעד אחד. אפשר לכתוב תנאי ארוך שבודק בכל פעם איזו דמות קיבלה את הפקודה. אפשר גם לתת לכל דמות להחליט בעצמה איך היא זזה.

האפשרות השנייה היא הלב של תכנות מונחה עצמים, או OOP. במקום שמקום מרכזי אחד יכיר כל פרט במערכת, מחלקים את התוכנה לאובייקטים עם נתונים, אחריות ופעולות ברורות. כך הקוד מתחיל להיראות כמו מערכת של חלקים שמשתפים פעולה.

בחומרי הלימוד המשולבים של Python ו-Java שנמסרו למכללה מופיעים יסודות Java, תכנות מונחה עצמים, ירושה, פולימורפיזם, ממשקי Swing ומשחקים קטנים. אלה מקורות ההקשר למאמר; התוכן כאן מסביר את המושגים ואינו מתאר התחייבות לגבי מסלול או מחזור לימוד נוכחי.

מפת מושגים

ארבע מילים, מערכת אחת

קל יותר לזכור את המושגים כשהם מחוברים לאותו משחק, ולא כשהם מופיעים כהגדרות נפרדות במילון.

מחלקה
GameCharacter
תבנית שמגדירה אילו נתונים ופעולות משותפים לדמויות.
אובייקט
wizard
דמות מסוימת שנוצרה מהמחלקה ומחזיקה מצב משלה.
ירושה
Wizard extends GameCharacter
מחלקה מיוחדת שמקבלת בסיס משותף ומוסיפה התנהגות משלה.
פולימורפיזם
character.move()
אותה פקודה מפעילה תוצאה מתאימה לפי סוג האובייקט בפועל.
דוגמת Java

אותה פעולה, שתי התנהגויות

מחלקת הבסיס מגדירה שלכל דמות יש שם ושכל דמות חייבת לדעת לזוז. היא אינה מחליטה איך. כל מחלקה יורשת מממשת את הפעולה בדרך שמתאימה לה.

בלולאה שבתחתית הקוד המשתנה מוכר כ-GameCharacter, אבל Java מפעילה בזמן הריצה את גרסת move של האובייקט האמיתי. זה פולימורפיזם: ממשק משותף, תגובות שונות.

abstract class GameCharacter {
  String name;

  GameCharacter(String name) {
    this.name = name;
  }

  abstract void move();
}

class Wizard extends GameCharacter {
  Wizard(String name) { super(name); }

  void move() {
    System.out.println(name + " glides");
  }
}

class Runner extends GameCharacter {
  Runner(String name) { super(name); }

  void move() {
    System.out.println(name + " dashes");
  }
}

for (GameCharacter character : team) {
  character.move();
}

ירושה היא כלי, לא ברירת מחדל

מבנה טוב לא נמדד לפי מספר המחלקות. הוא נמדד לפי השאלה אם כל קשר בקוד מסביר קשר אמיתי במערכת.

נתון ששייך לכל דמות

name או health

ממקמים במחלקת הבסיס כדי לא לחזור על אותו קוד.

פעולה עם מימוש שונה

move

מגדירים חוזה משותף ומממשים אותו בכל סוג דמות.

יכולת שניתנת רק לחלק מהדמויות

canFly

שוקלים ממשק או אובייקט יכולת, במקום להעמיס על כל היררכיית הירושה.

מעבדת ריפקטורינג

תרגיל שמתחיל מקוד מבולגן בכוונה

במקום להציג מיד פתרון מושלם, כותבים גרסה עם תנאים כפולים ואז משפרים אותה. המעבר בין הגרסאות מראה איזו בעיה OOP פותר בפועל.

  1. 1מתחילים משתי דמויות בלבד, למשל קוסם ורץ, כדי שההבדל בהתנהגות יהיה ברור.
  2. 2מסמנים נתונים שחוזרים בשתיהן ומעבירים רק אותם למחלקת בסיס.
  3. 3מחליפים תנאי ארוך בפעולה משותפת שכל דמות מממשת בדרכה.
  4. 4מוסיפים דמות שלישית בלי לשנות את לולאת המשחק ובודקים שהמבנה באמת גמיש.
  5. 5משנים חוק אחד ומריצים שוב את כל הדמויות כדי לזהות תלות לא צפויה.

שלוש שאלות שחוזרות בתחילת הדרך

האם חייבים להתחיל מירושה כדי ללמוד OOP?

לא. כדאי להתחיל ממחלקה ואובייקט, להבין מצב ופעולות, ורק אז להוסיף ירושה כשיש קשר אמיתי בין סוג כללי לסוג מיוחד.

למה לא לכתוב תנאי שבודק איזו דמות זו?

תנאי קטן יכול לעבוד, אבל כשהמשחק גדל הוא מרכז ידע על כל הדמויות במקום אחד. פולימורפיזם מאפשר לכל דמות להיות אחראית להתנהגות שלה.

איך יודעים שהתלמיד הבין ולא רק העתיק את הקוד?

מבקשים להוסיף דמות חדשה, להסביר מה עבר בירושה ולנבא איזו גרסת move תופעל. שינוי קטן חושף הבנה טוב יותר משינון הגדרות.