פרק לדוגמה - מבט לחלונות
Transcription
פרק לדוגמה - מבט לחלונות
פרק 1 מהו טיפוס מורכב? עד כה השתמשנו במושג טיפוס בשני הקשרים :לפני שנחשפנו למושגים של תכנות מונחה עצמים ,)intמשתנה דיברנו על טיפוס בהקשר של סוג הערך של משתנים .למשל :משתנה מטיפוס שלם ( מטיפוס ממשי ( ,)doubleמשתנה מטיפוס בוליאני ( .)boolבמסגרת תכנות מונחה עצמים דיברנו על הגדרת טיפוס על ידי המשתמש ,למשל :הטיפוסים תלמיד ( )Studentאו שיר (:)Song בספר יסודות מדעי המחשב – חלק ב' :במחלקה TestStudentבעמוד ,140הוגדר משתנה בשם stu1מטיפוס – Studentשערכו הוא עצם מן הטיפוס; בספר יסודות מדעי המחשב – חלק ב' :דוגמה פתורה 1בעמוד 153במחלקה SongProgram1 הוגדר משתנה בשם songsשהוא מערך של עצמים מטיפוס – Songערך של כל אחד מתאי המערך הוא עצם מן הטיפוס. טיפוס הוא טיפוס בכל מקרה ,גם אם הוא מוגדר בתוך שפת התכנות ,וגם אם הוא מוגדר על ידי המשתמש .כפי שמשתנה יכול להיות מוגדר על פי טיפוס שהוגדר על ידי המשתמש ,כך גם תכונה. – טיפוס תכונה של טיפוס חדש יכולה להיות מטיפוס אחר שהוגדר קודם על ידי המשתמש .כלומר המשתמש בטיפוס .לטיפוס כזה נקרא טיפוס מורכב. טיפוס מורכב -לשם מה? העיקרון עליו מושתת תכנות מונחה עצמים הוא חלוקת בעיה לטיפוסים הנדרשים לפתרונה וכן שימוש בטיפוסים שכבר הוגדרו (בשפה או ע"י המשתמש) לצורך הגדרת טיפוסים חדשים .פתרון בעיה בגישה מונחית עצמים מתחיל בזיהוי העצמים הנדרשים לפתרונה ,ובהתאם לכך הגדרה כללית של הטיפוסים שלהם .העצמים נבנים בהתאם לטיפוסים .דוגמה אחת לשילוב של טיפוסים היא למשל .)7באופן מערך של עצמים מטיפוס שהוגדר על ידי המשתמש (יסודות מדעי המחשב ,חלק ב ,פרק דומה ניתן לעשות שימוש בכל טיפוס שהגדיר המשתמש לצורך הגדרת טיפוסים חדשים. טיפוס מורכב הוא טיפוס המוגדר על ידי המשתמש שחלק מן התכונות שלו הן מטיפוס שאינו בסיסי בשפה אשר הוגדר על ידי המשתמש או שהוא כלול בספריות של השפה. הגדרה למשל :אם הוגדר הטיפוס גלגל ניתן להגדיר טיפוס מכונית שאחת התכונות שלו היא שיש בו גלגל .התכונה גלגל היא מן הטיפוס גלגל .כלומר הטיפוס מכונית משתמש בטיפוס גלגל. ................................................................................................................................... ..................................................................................................................................................... ..................................................................................................................................................... עיצוב תוכנה – טיפוס מורכב © כל הזכויות שמורות ל'מבט לחלונות' 7 הגדרה מושגים חדשים בפרק טיפוס בסיסי – טיפוס המוגדר כבנוי בשפה (מספר שלם ,מספר ממשי ,תו ,ערך בוליאני). טיפוס פשוט ( – )Simple classטיפוס המוגדר על ידי המשתמש שהתכונות שלו הן מטיפוסים בסיסיים. טיפוס מורכב ( – )Composed classטיפוס המוגדר על ידי המשתמש (או מוגדר בשפה) שחלק מן התכונות שלו הן מטיפוס שאינו בסיסי בשפה. טיפוס משתמש בטיפוס – טיפוס שבתוך ההגדרה שלו יש שימוש בטיפוס אחר שהוגדר על ידי המשתמש .השימוש יכול להיות בתכונה /בפרמטר /במשתנה /בערך מוחזר. מודולאריות ( – )Modularizationחלוקה של בעיה למספר טיפוסים המשתמשים זה בזה, ויכולים לשמש גם לצורך פתרון בעיות אחרות. הכמסה ( – )Encapsulationעצם על כל תכונותיו מומשל לכמוסה ומהווה יחידה אחת. כיחידה אחת העצם משמש כערך (אחד) של תכונה /משתנה /פרמטר /ערך מוחזר. דוגמה :1קלמר העצם עפרון ניתן כדוגמה לעצם ,עכשיו אנחנו כבר יודעים שלפני שאנו מתייחסים אל העצם עפרון יש להגדיר את הטיפוס עפרון .באותו אופן אנו יכולים להגדיר את הטיפוסים :מחדד ,מחק ומספריים . לכל אחד מן הטיפוסים האלה יש תכונות המאפיינות אותו ופעולות שניתן להפעיל על עצמים שנבנו על פיו .נבחר עצמים מכל טיפוס ונרצה להרכיב קלמר .ל קלמר יש בעלים ויש מחיר ויהיו בו 2עפרונות, מחדד ,מחק ,ומספריים ,כלומר – אלו התכונות שלו .קלמר מסוים יהיה של אדם מסוים ויהיה לו מחיר מסוים והוא יכיל – שני עפרונות מסוימים (עצמים מטיפוס עפרון) ,מחדד מסוים (עצם מטיפוס מחדד) ,מחק מסוים (עצם מטיפוס מחק) ,ומספריים מסוימים (עצם מטיפוס מספריים) .הקלמר הזה הוא עצם .יש הרבה קלמרים שזו תכולתם ,לכן ניתן להגדיר את הטיפוס קלמר .בטיפוס קלמר יוגדרו 7תכונות ,וכל תכונה היא מהטיפוס המתאים לה .הטיפוס קלמר יקרא טיפוס מורכב כי הוא משתמש בטיפוסים אחרים שהוגדרו על ידי המשתמש :עפרון ,מחדד ,מ חק ,מספריים .נקרא לעצם מן הטיפוס קלמר עצם מורכב ,מאחר וערכי התכונות שלו הם עצמים ולא טיפוסים בסיסיים. דוגמה :2שיחת טלפון ניתן לאפיין את התכונות הבאות עבור שיחת טלפון :קו-טלפון מתקשר ,קו-טלפון מקבל ,האדם המתקשר ,האדם המקבל ,זמן התחלת השיחה וזמן סוף השיחה .מאפיינים אלו משותפים לכל שיחות הטלפון ולכן מתאים להגדיר את הטיפוס שיחת-טלפון .מהו קו-טלפון? קו-טלפון אף הוא טיפוס שהתכונות שלו למשל הן :מספר הקו והבעלים של הקו .הערך של התכונה קו-טלפון מתקשר הוא קו-טלפון . עצם מטיפוס קו-טלפון .כך גם הערך של התכונה קו-טלפון מקבל הוא עצם מטיפוס הטיפוס שיחת-טלפון הוא טיפוס מורכב כי יש לו תכונות מטיפוס פשוט שהערכים שלהם הם עצמים. 8 עיצוב תוכנה – טיפוס מורכב © כל הזכויות שמורות ל'מבט לחלונות' ערך של משתנה/תכונה מטיפוס שהערכים שלהם הם עצמים. שיחת-טלפון הוא עצם מורכב ,כי יש לו תכונות מטיפוס פשוט דוגמה :3כיתה ובית ספר עסקנו רבות בטיפוס תלמיד .הגדרנו גם מערך של תלמידים .ניתן להשתמש במערך של תלמידים כתכונה של הטיפוס כיתה .לטיפוס כיתה יש את המאפיינים :שכבה ,מספר כיתה ,מחנך הכיתה, מערך תלמידי הכיתה .עצם מן הטיפוס כיתה יהיה כיתה מסוימת ,למשל כיתה בשכבה י' ,שמספרה ,7 המחנך שלה הוא שמואל שלומיאלי ,ויש בה תלמידים שכל אחד מהם הוא עצם במערך התלמידים. הטיפוס כיתה משתמש בטיפוס תלמיד .גם עבור המורה ניתן להגדיר טיפוס נפרד .במקרה זה הטיפוס כיתה היה משתמש בטיפוס תלמיד וגם בטיפוס מורה .ניתן להתייחס גם לטיפוס נוסף ,הטיפוס בית- ספר .המאפיינים של בית ספר הם למשל :שם ,עיר ,כתובת ,מערך מורי בית הספר ,ומערך כיתות ביה"ס .כלומר יש לנו טיפוס מורכב המשתמש בטיפוס מורה וגם בטיפוס כיתה ,כאשר הטיפוס כיתה משתמש בטיפוס מורה וגם בטיפוס תלמיד .האפשרות של פיתוח מודולארי -זו המשמעות ,החשיבות והיתרון של תכנות מונחה עצמים .בניית טיפוסים יכולה להתבצע באופן בלתי תלוי .בהתאם לצרכי פתרון הבעיה ישולבו טיפוסים בפרויקט ,כך שטיפוס יכול תמיד להשתמש בטיפוסים שהוגדרו קודם. לסיכום ,בשלוש הדוגמאות שהוצגו לעיל הדגש היה על התכונות של הטיפוסים שהערך שלהם הוא עצם .הכללים של הפעלת פעולות על עצמים נשמרים גם כאשר העצמים מהווים ערכים של תכונות בעצם אחר -מורכב .בכל מקרה על כל עצם ניתן להפעיל את אוסף הפעולות המוגדרות בטיפוס שלו. בטיפוס המורכב ,כמו בכל טיפוס ,מוגדרות תכונות ופעולות .הפעולות שיוגדרו בטיפוס מורכב הן פעולות שיופעלו על עצם מן הטיפוס הזה. לסיכום ,לעקרון המבנה של חלוקה מודולארית לטיפוסים יש חשיבות ומשמעות רבה .בעבודה עם טיפוס אחד בלבד אי אפשר להוציא אל הפועל באופן משמעותי את העקרונות של תכנות מונחה עצמים .העקרונות של תמ"ע והיתרונות שלהם באים לידי ביטוי כאשר יש שילוב ושימוש במספר טיפוסים כמו למשל בדוגמה של השילוב בין הטיפוסים :תלמיד ,מורה ,כיתה ,ביה"ס. שפת UML שפת (Unified Modeling Language) UMLהיא שפה הכוללת אוסף של סימונים מוסכמים לתיאור מערכת תוכנה מהיבטים שונים .קיום של שפת תיאור אחידה מהותי כדי שמפתחים שונים וקוראים שונים של תוכנה יוכלו להתמצא בה ולמעשה "לדבר באותה שפה" .השפה כוללת כללים לתיאורים גראפיים שונים של מערכת תוכנה מנקודות מבט שונות וקיימת הסכמה רחבה בתעשייה להשתמש בה כסטנדרט .בספר זה נשתמש בשני מרכיבי תיאור מתוך ה )1( :UML -תיאור מחלקה -הכולל :שם, תכונות ופעולות; ( )2תרשים מחלקות – תרשים המתאר את הקשר בין מחלקות שונות בפרויקט. קיימים סוגים שונים של קשרים בין מחלקות .ביחידת לימוד זו הקשר היחיד בו נשתמש הוא קשר של שימוש/הכלה – הבא לידי ביטוי כאשר במחלקה אחת יש תכונות מטיפוס של מחלקה אחרת. עיצוב תוכנה – טיפוס מורכב © כל הזכויות שמורות ל'מבט לחלונות' 9 ייצוג של טיפוס מורכב בתרשים טיפוס מורכב מיוצג בהתאם לכללי הייצוג עבור כל טיפוס .בתרשימים הבאים נפרט עבור כל תכונה גם את הטיפוס שלה .נציג את הטיפוסים המתוארים בדוגמה 3על ידי תרשים .UMLבתרשים UML המתאר מחלקה בדרך כלל לא מופיעה העמודה הימנית – כי מוסכם שאלו החלקים הקיימים בתיאור של כל מחלקה .תרשימי UMLכתובים בשפת התכנות ולא בשפה טבעית .בדוגמה זו יוצג תרשים בעברית .בדוגמאות הבאות נעבור לייצוג פורמאלי בשפת .UML :הטיפוס בנקודת המעוין משתמש בטיפוס שהקו מתחיל ממנו. משמעות הקו הסבר :לטיפוס בנקודת המעוין קימת לפחות תכונה אחת מטיפוס המוצא. לדוגמה קו – 1בטיפוס כיתה יש תכונה המשתמשת בטיפוס מורה :התכונה מחנך מטיפוס מורה. הטיפוס בנקודת המעוין משתמש בטיפוס שהקו מתחיל ממנו שלא בתור תכונה. משמעות הקו הטיפוס תלמיד הטיפוס מורה תכונות שם מטיפוס מחרוזת ת.ז .מטיפוס מחרוזת ציון במתמטיקה מטיפוס שלם מטיפוס שלם ציון באנגלית מטיפוס שלם ציון בלשון תכונות שם מטיפוס מחרוזת ת.ז .מטיפוס מחרוזת ותק בהוראה מטיפוס שלם בעל תעודת הוראה מטיפוס בוליאני מקצועות הוראה מטיפוס מערך מחרוזות פעולות העלה-ציון(_מקצוע_ ,נקודות) החזר-ממוצע( ) הדפס-תעודה( ) פעולות הגדל-ותק-בשנה( ) הוסף-מקצוע-הוראה(_מקצוע) האם-מלמד-מקצוע(_מקצוע) 2 הטיפוס כיתה תכונות מטיפוס תו שכבה מטיפוס שלם מספר מטיפוס מורה מחנך מספר תלמידים מטיפוס שלם מטיפוס מערך של תלמידים תלמידים פעולות הוסף-תלמיד(_תלמיד) קבע-מחנך(_מורה) האם-תלמיד-לומד-בכיתה(_תלמיד) החזר-תלמיד-מצטיין( ) הטיפוס 4 הערה :התרשים כולל הגדרת תכונות מלאה והגדרת פעולות חלקית .אין למשל פעולות בונות. 10 עיצוב תוכנה – טיפוס מורכב © 1 3 בית ספר תכונות שם עיר מורים כיתות פעולות הוסף-תלמיד-לכיתה(_שכבה_ ,מספר_ ,תלמיד) הוסף-מורה(_מורה) באיזו-כיתה-תלמיד-לומד(_תלמיד) החזר-תלמיד-מצטיין( ) מטיפוס מחרוזת מטיפוס מחרוזת מטיפוס מערך של מורים מטיפוס מערך של כיתות כל הזכויות שמורות ל'מבט לחלונות' הסבר החיצים בתרשים: קו – 1בטיפוס כיתה יש תכונה המשתמשת בטיפוס מורה :התכונה מחנך מטיפוס מורה. קו – 2בטיפוס כיתה יש תכונה המשתמשת בטיפוס תלמיד :התכונה תלמידים מטיפוס מערך של תלמיד. קו – 3בטיפוס בית ספר יש תכונה המשתמשת בטיפוס מורה :התכונה מורים מטיפוס מערך של מורה. קו – 4בטיפוס בית ספר יש תכונה המשתמשת בטיפוס כיתה :התכונה כיתות מטיפוס מערך של כיתה. תרשים מסוג זה מתאר את הקשרים שיש בין טיפוסים ומקל מאד על תהליך תכנון הטיפוסים הכולל את זיהוי התכונות והפעולות שלהם ,ומקל גם על פיתוח הפעולות תוך שימוש בפעולות המוגדרות בטיפוסים האחרים. שים :הפעולה החזר-תלמיד-מצטיין( ) מוגדרת בשני טיפוסים .הפעולה המוגדרת בטיפוס כיתה תופעל על עצם מטיפוס כיתה ותחזיר את התלמיד המצטיין בכיתה .הפעולה המוגדרת בטיפוס ביה"ס תופעל על עצם מטיפוס ביה"ס ותחזיר את התלמיד המצטיין בביה"ס .גם בשפת התכנות ניתן להגדיר פעולות בעלות שם זהה בטיפוסים שונים .מאחר ובזמן הפעלת הפעולה היא תופעל על עצם מסוים, ועצם יכול להיות רק מטיפוס אחד ,אין בעיה בזיהוי הפעולה שיש לבצע .הפעולה שתתבצע היא זו המוגדרת בטיפוס של העצם עליה היא מופעלת. כללי הפיתוח של טיפוס מורכב הם בדיוק כמו כללי הפיתוח של כל טיפוס. נדגים בשלבים פיתוח לטיפוס כיתה ,StudentClassבהנחה שהטיפוסים תלמיד – ,Studentו מורה – Teacherמוגדרים. המימוש המלא של הטיפוס המורכב כיתה-בית ספר :בעמוד 19בספר. את הקבצים ניתן לראות באתר האינטרנט בכתובת www.mabatl.co.il עיין באתר אינטרנט בחר בקישוריות 'פרויקט כיתה-פרק '1 בקטגוריה :אתרים מלווי ספרים לחץ על במהלך הגדרת הטיפוס ניתן דגשים באשר לעצמים המשמשים כערך של תכונה ,כערך של פרמטר ,או כערך מוחזר. דיאגרמת המחלקות שמשתתפות בפרויקט זה היא: Student Teacher School עיצוב תוכנה – טיפוס מורכב StudentClass © כל הזכויות שמורות ל'מבט לחלונות' 11 StudentClass של המחלקהUML תרשים StudentClass private char level private int number private Teacher educator private int numOfStudents private Student[] students public StudentClass(char level, int number, Teacher educator, int numOfStudents) public StudentClass(char level, int number) public void AddStudent(Student stu) public char GetLevel() public int GetNumber() public int GetNumStudents public Teacher GetEducator() public Student GetStudent(string id) public int GetNumOfStudents() public Student[] GetStudents() public void SetLevel(char level) public void SetNumber(int number) public void SetEducator(Teacher educator) public void SetNumOfStudents(int numOfStudents) public void SetStudents(Student[] students) public Student BestInClass() public bool IsStudentInClass(Student stu) public bool RaiseGrade(string id, string subject, int points) הגדרת התכונות .הגדרת תכונה שהיא מטיפוס אחר של המשתמש מתבצעת בדיוק כמו הגדרה של כל תכונה אחרת .תחילה מופיע טיפוס התכונה ואחר כך השם שלה StudentClass הגדרת תכונות המחלקה public class StudentClass היא,educator – התכונה מחנך:הסבר { הערך של התכונה.Teacher - מטיפוס מורה char level; כיצד בהמשך נראה.יהיה עצם מטיפוס מורה int number; Teacher educator; .תכונה זו מקבלת את הערך שלה int numOfStudents = 0; היא מערך של,students – התכונה תלמידים Student[] students = new Student[30]; , במקרה זה.Student – עצמים מטיפוס תלמיד } , תאי המערך30 בהגדרת התכונה נבנו גם מוגדרת, מאחר ולא בכל כיתה יש מספר תלמידים זהה. תלמידים30 בכיתה יכולים להיות עד,כלומר תכונה זו מייצגת את מספר התלמידים.numOfStudents – גם התכונה מספר תלמידים בכיתה הערך של התכונה הזו ינוהל כולו על ידי הפעולות בטיפוס זאת מאחר והוא חייב.בכיתה מסוימת .להיות תואם לתלמידים המושמים במערך התלמידים 'כל הזכויות שמורות ל'מבט לחלונות © 12 עיצוב תוכנה – טיפוס מורכב עצמים כערכים של תכונות ערכים של משתנים שהם מטיפוס של המשתמש הם עצמים ועל משתנים אלו ניתן להפעיל את הפעולות המוגדרות בטיפוס שלהם .עצם מטיפוס נקרא גם מופע של הטיפוס. לדוגמה במחלקה ראשית TestStudentניתן להגדיר מערך של עצמים מטיפוס :Student ;]Student[] stu = new Student[30 בדיוק באותו אופן מגדירים ומשתמשים בתכונות שהן מטיפוס של המשתמש ,שהערכים שלהן הם עצמים .למשל בגוף הפעולה הבונה ) StudentsClass(….תהיה השמה לתכונה :students ;this.students = students הכללים שהותוו לגבי תכונות של טיפוס פשוט זהים גם לתכונות מטיפוס מורכב .גם לתכונות אלו תוגדרנה פעולה קובעת ופעולה מאחזרת למשל פעולה מאחזרת ופעולה קובעת למורה של כיתה: )(public Teacher GetEducator { ;return educator } )public void SetEducator(Teacher educator { ;this.educator = educator } בכל מקרה ההתייחסות למשתנה/תכונה/פרמטר מטיפוס בסיסי כמו intשהערך שלו הוא מספר שלם כלשהו ,זהה להתייחסות למשתנה/תכונה/פרמטר שהוא מטיפוס Studentשהערך שלו הוא עצם מטיפוס זה .כלומר ,פרמטרים המועברים לפעולות וגם ערכים המוחזרים על ידי פעולות ,יכולים להיות מטיפוס של המשתמש ויכילו עצמים .בסעיפים הבאים נסביר ונדגים את השימושים האפשריים בתכונה שהיא מטיפוס של המשתמש והערך שלה הוא עצם. העצם הנוכחי this - כל פעולה המוגדרת בטיפוס המייצג ישות תופעל על עצם מן הטיפוס .לפעמים יש צורך להתייחס אל העצם הנוכחי עליו מופעלת הפעולה .במקרה זה משתמשים במילה השמורה .thisאין הכרח להשתמש בה אך מקובל להשתמש בה במקומות שיוסברו להלן. פעולות בונות ופעולות קובעות מקבלות פרמטרים שמטרתם להעביר ערכים לאתחול/עדכון של תכונות .מקובל להשתמש בפרמטר שיש לו שם זהה לשם התכונה .למשל אם התכונה היא number הפרמטר שצריך לעדכן אתה יהיה אף הוא .number אם כך משפט ההשמה יהיה ;? number = number במקרה של הגדרה כזו הקומפיילר מתייחס למשתנה numberשהוגדר כפרמטר משני צידי משפט ההשמה ולא יתייחס כלל לתכונה .אם רוצים להתייחס אל התכונה יש לומר שמתייחסים ל number של העצם הנוכחי. ;this.number = number משפט ההשמה של ערך הפרמטר לתכונה יוגדר אם כן כך: מצד שמאל של משפט ההשמה – this.numberמתייחס אל התכונה numberשל העצם הנוכחי, כלומר ,העצם עליו מופעלת הפעולה .מצד ימין של משפט ההשמה – numberמתייחס אל הפרמטר .number בספר זה יהיה שימוש בפניה לעצם הנוכחי thisרק במקרים אלה. עד כה ראינו את סימן הנקודה ( )dot notationעבור הפעלת פעולה על עצם .גם כאן השימוש בסימן הנקודה מתייחס לעצם – לעצם הנוכחי הסמוי ,אך הפנייה היא לתכונה ולא לצורך הפעלת פעולה. עיצוב תוכנה – טיפוס מורכב © כל הזכויות שמורות ל'מבט לחלונות' 13 בטיפוס מורכב נגדיר פעולות לפי אותן קטגוריות שתוארו בטיפוס פשוט: פעולות בונות – עמוד 14 פעולות מאחזרות – עמוד 16 פעולות קובעות – עמוד 16 פעולות חישוביות המחזירות עצם – עמוד 17 פעולות חישוביות המקבלות עצם כפרמטר – עמוד 18 פעולות בונות פעולה בונה היא פעולה שתמיד מחזירה עצם חדש .השלבים המתבצעים בהפעלת פעולה בונה הם: )1הקצאת שטחי זיכרון לעצם בהתאם להגדרת התכונות שלו ולטיפוסים שלהן. )2אתחול ערכי כל התכונות בערכי ברירת המחדל על פי הטיפוסים שלהם. )3ביצוע גוף הפעולה הבונה .אם גוף הפעולה הבונה כולל השמת ערכים חדשים לתכונות הם כמובן מתעדכנים. )4החזרת העצם שנבנה (למעשה החזרת הפנייה אל העצם החדש). פעולה בונה בטיפוס מורכב תוגדר באותו אופן בו הוגדרה עבור טיפוס פשוט .התבנית הסטנדרטית של הפעולה הבונה היא זו המקבלת פרמטר עבור כל אחת מן התכונות שלה ,ומשימה את ערכי הפרמטרים להיות ערכי התכונות. לדוגמה הגדרת פעולה בונה בטיפוס כיתה המקבלת פרמטר לכל תכונה: public StudentClass(char level, int number, Teacher educator, int numOfStudents, )Student[] students { ;this.level = level ;this.number = number ;this.educator = educator ;this.numOfStudents = numOfStudents הסבר הפתרון ;this.students = students } הסבר :הפרמטר educatorהוא מטיפוס Teacherובגוף הפעולה הוא מושם לתכונה educatorשהיא מטיפוס .Teacherהפרמטר studentsהוא מטיפוס מערך של סטודנטים ][ ,Studentוהוא מושם לתכונה studentsשאף היא מן הטיפוס מערך של סטודנטים ][.Student ניתן להגדיר במחלקה מספר פעולות בונות ובלבד שרשימת הפרמטרים שלהם תהיה מובחנת ,כלומר, לא יכולות להיות שתי פעולות בונות שיש להן פרמטרים מאותם טיפוסים ובאותו הסדר .די שיהיה שינוי אחד ,למשל :בטיפוס של פרמטר ,במספר הפרמטרים או בסדר הפרמטרים הכולל שינוי בסדר הטיפוסים שלהם .ניתן להגדיר פעולה בונה נוספת שמשימה ערכים מפרמטרים רק לחלק מן התכונות ויתר הערכים של התכונות יקבעו תחילה על ידי ערכי ברירת מחדל ,ומאוחר יותר לפי הצורך על ידי פעולות קובעות או פעולות חישוביות אחרות. 14 עיצוב תוכנה – טיפוס מורכב © כל הזכויות שמורות ל'מבט לחלונות' לדוגמה פעולה בונה נוספת בטיפוס כיתה המקבלת רק שני פרמטרים: )public StudentClass(char level, int number { ;this.level = level ;this.number = number } פעולה בונה מעתיקה חושבים רגע.. כיצד נקבל העתק של עצם? כאשר אנו משתמשים בטיפוסים בסיסיים ויש צורך במשתנה נוסף עם אותו ערך ,פשוט מבצעים השמה .נעקוב אחר קטע הקוד הבסיסי שלהלן: הוראה x y הסבר :אחרי ההשמה של ערך xל y ,y -הוא 8 ;int x = 8 העתק של – xבשניהם יש את אותו ערך .שינוי 8 8 ;int y = x של xלאחר מכן לא משנה את .y 9 8 ;x = 9 מה קורה ביחס לעצמים? למשל ביחס לעצמים מן הטיפוס .Songנסתכל על אותו רצף של הוראות: ;)Song sx = new Song("Jerusalem", "Yael", 190 ;Song sy = sx ;)sx.SetLength(200 מה אורך השיר ?sxמה אורך השיר ?sy sx: Song נעקוב אחר הקצאת הזיכרון עבור העצמים: בעקבות ההוראהSong sx = new Song("Jerusalem", "Yael", 190); : תתקבל תמונת הזיכרון הבאה: Jerusalem Yael 190 : Jerusalem: Yael 200 performer: Length sx: Song sy: Song ;Song sy = sx בעקבות ההוראה: תתקבל תמונת הזיכרון הבאה: name: name: performer: Length: כלומר הוקצה משתנה syמטיפוס Songאך הוא הפנייה – לא נבנה עצם חדש ,לא הוקצו שטחי זיכרון חדשים sx, sy .מפנים אל אותו עצם. לכן לאחר ביצוע קביעה של ערך חדש לאורך השיר ,sxהעדכון חל גם על syכי זה אותו העצם. כלומר :ההוראה ;) sx.SetLength(200תעדכן את ערך התכונה שהוא משותף ל sx, sy -כי הם רק הפניות שונות אל אותו עצם!!! לכן ,אם רוצים ליצור עותק עצמאי של עצם יש צורך לבנות אותו ע"י פעולה בונה ,אחרת לא יוקצו עבורו שטחי זיכרון חדשים. פעולה בונה מעתיקה היא פעולה בונה המקבלת עצם מאותו הטיפוס ומחזירה עצם חדש (שטחי זיכרון חדשים) אשר ערכי התכונות שלו זהים לערכי התכונות של העצם בפרמטר. עבור הטיפוס Songנגדיר את הפעולה הבונה המעתיקה הבאה: עיצוב תוכנה – טיפוס מורכב © כל הזכויות שמורות ל'מבט לחלונות' 15 שים :אין בעיה שפעולה בונה במחלקה Songתקבל כפרמטר עצם מאותה המחלקה. באופן דומה ניתן להגדיר פעולה בונה מעתיקה גם עבור טיפוס מורכב. )public Song(Song s { ;this.name = s.name ;this.performer = s.performer ;this.length = s.length } העמסת פעולות הדוגמאות שהוצגו עבור הגדרות שונות לפעולה מתאפשרות עקב המנגנון של העמסת פעולות ( .)methods overloadמאחר ויש הבחנה בכותרת של הפעולות ,הבאה לידי ביטוי ברשימת הפרמטרים שלה ,הפעולות יכולות להיות בעלות שם זהה .מנגנון זה פועל ביחס לכל סוגי הפעולות המוגדרות ולא רק ביחס לפעולה בונה. פעולות מאחזרות השימוש בערכים שהם עצמים זהה לשימוש בכל ערך אחר .כפי שפעולה יכולה להחזיר ערך מטיפוס intאו boolאו ,stringהיא יכולה להחזיר ערך שהוא עצם מטיפוס Studentאו מטיפוס Teacherאו מטיפוס .StudentClassבהתאם לכלל המקובל יש להגדיר פעולה מאחזרת לכל תכונה ,בין אם התכונה מטיפוס פשוט ובין אם טיפוס התכונה מטיפוס שהוגדר על ידי המשתמש .במקרה שהתכונה מטיפוס שהוגדר על ידי המשתמש ,יוחזר עצם שהוא הערך של התכונה. נסתכל לדוגמה על מספר פעולות מאחזרות שניתן להגדיר בטיפוס כיתה: הפעולה ומשמעותה מטרת הפעולה :הפעולה מאחזרת את ערך התכונה מחנך. הסבר :טיפוס הערך המוחזר על ידי הפעולה הוא Teacher כטיפוס התכונה .educatorכלומר מוחזר עצם מטיפוס מורה. מטרת הפעולה :הפעולה מאחזרת את ערך התכונה מערך תלמידים .הסבר :טיפוס הערך המוחזר על ידי הפעולה הוא ][ Studentכטיפוס התכונה .studentsכלומר מוחזר עצם מטיפוס מערך תלמידים. קוד הפעולה )(public Teacher GetEducator { ;return this.educator } )(public Student[] GetStudents { ;return this.students } פעולות קובעות מטרת פעולה קובעת היא לקבוע ערך לתכונה .באותו אופן בו הפעולה הבונה שהוגדרה לעיל קיבלה פרמטר שהערך שלו הוא עצם והשימה אותו בתכונה המתאימה ,תוגדר גם הפעולה הקובעת המתאימה לתכונה .נסתכל לדוגמה על מספר פעולות קובעות שניתן להגדיר בטיפוס כיתה: קוד הפעולה הפעולה ומשמעותה מטרת הפעולה :הפעולה קובעת את ערך התכונה מורה. הסבר :טיפוס הפרמטר הוא Teacherכטיפוס התכונה educatorשאת הערך שלה קובעת הפעולה ,כלומר, מושם בתכונה עצם (כמוסה) מטיפוס מורה. 16 עיצוב תוכנה – טיפוס מורכב © public void SetEducator(Teacher )educator { ;this.educator = educator } כל הזכויות שמורות ל'מבט לחלונות' מטרת הפעולה :הפעולה קובעת את ערך התכונות: מספר תלמידים בכיתה ומערך התלמידים בכיתה. הסבר :טיפוס הפרמטר עבור מערך תלמידי הכיתה הוא ][ Studentכטיפוס התכונה studentsשאת הערך שלה הפעולה קובעת .כלומר מושם בתכונה עצם מטיפוס מערך תלמידים. ][public void SetStudents(Student )students, int numOfStudents { ;this.students = students ;this.numOfStudents=numOfStudents } פעולות קובעות ומאחזרות – הרחבה נהוג להגדיר פעולה קובעת ומאחזרת לכל תכונה כך שתהיה גישה לתכונות ע"י פעולות ולא באופן ישיר .נוהג זה הוא יישום של עיקרון הסתרת המידע הבא לידי ביטוי בשני מובנים )1 ( :הסתרת הייצוג הפנימי )2 ( ,מתן אחריות למפתח מחלקה להחליט לאילו תכונות יש גישה לצורך אחזור ו/או עדכון. למשל :אם מחלקה מממשת משחק ניחושים של ערך שלם ,לא תהיה גישה לאחזור הערך אותו יש לנחש; אם מחלקה מממשת ניהול שיחות טלפון לא תהיה אפשרות למשתמש במחלקה לשנות את זמן תחילת השיחה .כלומר :למרות הכלל להגדיר פעולה מאחזרת וקובעת לכל תכונה – מפתח מחלקה מפעיל שיקול דעת ויכול להסיר חלק מהן בהתאם לצורך. לעיתים יש צורך בפעולות שהן מאחזרות או קובעות לא עבור תכונה אלא עבור חלק ממנה .דוגמה טובה לכך היא בשימוש במערכים .למשל בפעולה הבאה או בפעולות המופיעות להלן בתרגילים :4 ,3 הפעולה ומשמעותה קוד הפעולה מטרת הפעולה :הפעולה מוסיפה תלמיד לכיתה .הנחה: מספר התלמידים בכיתה קטן מן המקסימום האפשרי. הסבר :טיפוס הפרמטר הוא Studentכטיפוס תא במערך התלמידים המיוצג בתכונה ,studentsאליו מוסיפים תלמיד .כדי להוסיף את התלמיד יש להשים בתא המערך המתאים את התלמיד החדש ולקדם את התכונה המייצגת את מספר התלמידים בכיתה ב.1- )public void AddStudent(Student stu { ;students[numOfStudents] = stu ;numOfStudents++ } פעולות חישוביות המחזירות עצם פעולות חישוביות יכולות להחזיר עצמים בדומה לפעולות המאחזרות .לדוגמה פעולה בטיפוס כיתה המחזירה את התלמיד בעל ממוצע הציונים הגבוה ביותר (בהנחה שיש רק תלמיד אחד כזה): )(public Student BestInClass { ;]Student bestStudent = students[0 )for (int i = 1 ; i<this.numOfStudents ; i++ { ))(if bestStudent.Average()>students[i].Average { ;]bestStudent = students[i } } ;return bestStudent } הסבר הפתרון הסבר :הפעולה תופעל על עצם מטיפוס כיתה .הפעולה לא צריכה לקבל פרמטרים לצורך ביצוע bestStudentמכיל את משימת החישוב שלה .בגוף הפעולה נסרק מערך התלמידים .העצם עיצוב תוכנה – טיפוס מורכב © כל הזכויות שמורות ל'מבט לחלונות' 17 לתלמיד בעל הממוצע הגבוה ביותר שנבדק עד כה .בתום סריקת המערך מוחזר התלמיד המתאים התלמיד .bestStudentהערך המוחזר על-ידי הפעולה הוא עצם מטיפוס תלמיד .עובדה זו באה Studentהמופיע בכותרת לידי ביטוי בשני מקומות :האחד ,בהגדרת טיפוס הערך המוחזר הפעולה .השני ,מאחר והמערך studentsהוא מערך של תלמידים אזי תא המערך ] students[iהוא תלמיד .שים :מאחר וכל תא במערך הוא מטיפוס תלמיד ,ניתן להפעיל על עצם מטיפוס תלמיד את הפעולה )( Averageהמוגדרת בטיפוס תלמיד .למשל ,הזימון )( students[i].Averageמחזיר את ממוצע הציונים של התלמיד שנמצא במערך במקום .i יתרון משמעותי של המודולאריות ,שהיא אחד מעקרונות היסוד של תכנות מונחה עצמים ,הוא אי-תלות בייצוג של התכונות .למשל ,בפרק ,7עודכנו התכונות בטיפוס תלמיד כך שהציונים יהיו במערך של ציונים ולא רק ציונים ב 3 -מקצועות .בהתאמה הוגדרה שם גם פעולה המחשבת את הממוצע שחתימתה זהה )( .Averageכלומר ,גם אם בפרויקט ישולב הטיפוס Studentהמקורי, או הטיפוס Studentהמורחב למערך ציונים ,לא יהיה צורך לשנות דבר בטיפוס כיתה המוגדר כאן. פעולות חישוביות המקבלות עצם כפרמטר הסבר הפתרון פעולות חישוביות יכולות לקבל פרמטרים שהערכים שלהם הם עצמים ,בדומה לפעולות הקובעות המקבלות פרמטר שהוא עצם .לדוגמה ,פעולה בטיפוס כיתה המקבלת תלמיד stuומחזירה אמת אם התלמיד נמצא בכיתה זו או שקר אם הוא לא נמצא בכיתה זו .ההשוואה מתבצעת על פי ת.ז. )public bool IsStudentInClass(Student stu { )for (int i=0 ; i<this.numOfStudents ; i++ { ))(if (students[i].GetIdNum()==stu.GetIdNum ;return true } ;return false } הסבר :הפעולה תופעל על עצם מטיפוס כיתה שיש לו את התכונה - studentsמערך של תלמידים. הפעולה סורקת את מערך התלמידים בהתאם למספר התלמידים הנמצא בתכונה numOfStudents ובודקת האם התלמיד במקום iבמערך הוא התלמיד שמספר ת.ז .שלו זהה לתלמיד stuשהתקבל בפרמטר .אם מספר ת.ז .נמצא מוחזר הערך אמת ,אחרת בתום סריקת המערך מוחזר הערך שקר. נסביר בהרחבה את הביטוי הבוליאני: )(students[i].GetIdNum() == stu.GetIdNum על התלמיד stu הפעל את הפעולה: אחזר מספר ת.ז. על התלמיד מספר i במערך התלמידים הפעל את הפעולה: אחזר מספר ת.ז. הפעל את האופרטור == לבדוק האם שני מספרי תעודות הזהות (שהם מחרוזות) -זהים 18 עיצוב תוכנה – טיפוס מורכב © כל הזכויות שמורות ל'מבט לחלונות' מחלקה ראשית אינה מייצגת טיפוס נתונים כמו תלמיד או שיר או כיתה או רובוט ,אלא מחלקה בה מתבצעת משימה .במחלקה זו מוגדרים העצמים ומופעלות עליהם פעולות .בדומה למחלקה הראשית בה בנינו עצמים מטיפוס של המשתמש (פרק 6ביסודות חלק ב) ,ובדומה להגדרת מערך של עצמים (פרק 7ביסודות חלק ב) ,נגדיר מחלקה ראשית שבפעולה הראשית שלה מוגדרים משתנים מטיפוס מורכב .אין כל שינוי בעקרונות הפיתוח של המחלקה הראשית. דוגמה למחלקה ראשית המגדירה עצמים מטיפוס מורכב נגדיר מחלקה ראשית .Programיחד עם מחלקה זו קיימים בפרויקט הטיפוסים,Teacher ,Student : ו .StudentClass -הטיפוסים מוגדרים בהתאם לתרשימי ה UML -בתחילת הפרק .בפעולה הראשית של המחלקה Programמתבצע האלגוריתם הבא: )1בנה מורה חדש ע"י שימוש בפעולה הבונה )( Teacherוהשם אותו במשתנה .oneTeacher )2הוסף למורה מקצוע שני כלשהו. )3בנה כיתה ע"י שימוש בפעולה הבונה )( StudentClassלתוך .class1 )4בנה תלמיד ראשון ע"י שימוש בפעולה הבונה )( Studentוהכנס אותו לכיתה .class1 )5בנה תלמיד שני ע"י שימוש בפעולה הבונה )( Studentוהכנס גם אותו לכיתה .class1 )6הדפס את התעודה של התלמיד המצטיין בכיתה .class1 נציג להלן קטע קוד של המחלקה הראשית .Program ;using System class Program { )static void Main(string[] args { מייצרים מורה ;)Teacher oneTeacher = new Teacher("Shira more","55555",10,true,"english",3 מוסיפים למורה מקצוע ;)"oneTeacher.AddSubject("grammer מייצרים כיתה עם המורה ;)StudentClass class1 = new StudentClass('A', 2,oneTeacher,30 המשמש כמחנך הכיתה מוסיפים תלמיד לכיתה ;))class1.AddStudent(new Student("Amir cohen","77777",90,90,80 מוסיפים תלמיד נוסף class1.AddStudent(new Student("Maor levi", "88888", 90, 90, 70b ;)))(Console.WriteLine(class1.StudentDetails(class1.BestInClass מדפיסים את נתוני התלמיד המצטיין בכיתה. } } } עיצוב תוכנה – טיפוס מורכב © כל הזכויות שמורות ל'מבט לחלונות' 19 דוגמה פתורה בית ספר- הטיפוס כיתה:1 דוגמה פתורה .בית ספר-להלן הקוד המלא לפרויקט כיתה using System; using System.Collections.Generic; מחלקה ראשית using System.Text; namespace BookMabatPage10 { class Program { static void Main(string[] args) { Teacher oneTeacher=new Teacher("Shira more","55555",10,true,"english",3); oneTeacher.AddSubject("grammer"); StudentClass class1 = new StudentClass('A', 2,oneTeacher,30); class1.AddStudent(new Student("Amir cohen","77777",90,90,80)); if (class1.AddStudent(new Student("Maor levi", "88888", 90, 90, 70))) { Console.WriteLine("The next student added to class"); Console.WriteLine(class1.StudentDetails("88888")); } else { Console.WriteLine("Sorry Maor the class is full"); } דוגמת הרצה if (!class1.IsStudentInClass("77777")) { The next student added to class Console.WriteLine("Student with id:77777 is not in the class"); name:Maor levi,id:88888 math:90 english:90 grammer:70 } The student before racing english else grade { cohen,id:77777 Console.WriteLine("The student before racing english grade");name:Amir math:90 english:90 grammer:80 Console.WriteLine(class1.StudentDetails("77777")); The student after racing english grade class1.RaiseGrade("77777", "english", 10); name:Amir cohen,id:77777 Console.WriteLine("The student after racing english grade"); math:90 english:100 grammer:80 Console.WriteLine(class1.StudentDetails("77777")); The next student is the best in class: } name:Amir cohen,id:77777 Console.WriteLine("The next student is the best in class:"); math:90 english:100 grammer:80 Console.WriteLine(class1.StudentDetails(class1.BestInClass())); class:A2 Console.WriteLine(class1); educator name:Shira more,id:55555 working years:10 has Diploma:True } subects:english grammer } students list: } name:Amir cohen,id:77777 math:90 english:100 grammer:80 name:Maor levi,id:88888 math:90 english:90 grammer:70 Press any key to continue . . . 'כל הזכויות שמורות ל'מבט לחלונות © 20 עיצוב תוכנה – טיפוס מורכב using System; Student המחלקה using System.Collections.Generic; using System.Text; namespace BookMabatPage10 { class Student { private string name; private string id; private int mathGrade; private int englishGrade; private int grammerGrade; public Student(string name, string id, int mathGrade,int englishGrade, int grammerGrade) { this.name = name; this.id = id; this.mathGrade = mathGrade; this.englishGrade = englishGrade; this.grammerGrade = grammerGrade; } public string GetName() { if(subject=="grammer") return this.name; { } this.grammerGrade+=points; public string GetId() return true; { } return this.id; return false; } } public int GetMathGrade() public void SetName(string name) { { return this.mathGrade; this.name = name; } } public int GetEnglishGrade() public double Average() { { return this.englishGrade; int sum = } this.mathGrade+this.englishGrade+this public int GetGrammerGrade() .mathGrade; { return sum / 3.0; return this.grammerGrade; } } public override string ToString() public bool RaiseGrade(string subject, int { points) string s = ""; { s += "name:" + if (subject == "english") this.name+","+"id:"+this.id+"\n"; { s += "math:" + this.mathGrade + " this.englishGrade += points; english:" + this.englishGrade + " return true; grammer:" + this.grammerGrade + "\n"; } return s; if (subject == "math") } { } this.mathGrade += points; } return true; } 21 'כל הזכויות שמורות ל'מבט לחלונות © עיצוב תוכנה – טיפוס מורכב StudentClass המחלקה using System; } using System.Collections.Generic; public string BestInClass() using System.Text; { namespace BookMabatPage10 int i; { Student bestStudent = this.students[0]; class StudentClass for (i = 1; i < this.numStudentes; i++) { { private char level; if (this.students[i].Average()> private int number; bestStudent.Average()) private Teacher educator; { bestStudent = this.students[i]; private int numStudentes; } private Student[] students; } public const int STANDART = 42; return bestStudent.GetId(); public StudentClass(char level, int number, } Teacher educator,int maxStudents) public bool IsStudentInClass(string id) { { this.level = level; return GetStudent(id) != null; this.number = number; } this.educator = educator; public string StudentDetails(string id) this.numStudentes = 0; { this.students = new Student[maxStudents]; Student stu = GetStudent(id); } if (stu != null) public StudentClass(char level, int number) { { return stu.ToString(); this.level = level; } this.number = number; return null; this.numStudentes = 0; } this.students = new Student[STANDART]; private Student GetStudent(string id) } { public char GetLevel() int i; { for (i = 0; i < this.numStudentes; i++) return this.level; { } if (this.students[i].GetId() == id) public int GetNumber() { { return this.students[i]; return this.number; } } } public int GetNumStudents() return null; { } return this.numStudentes; public bool RaiseGrade(string id, string subject, int } points) public void SetLevel(char level) { { Student stu = GetStudent(id); this.level = level; if (stu == null) } { public void SetEducator(Teacher educator) return false; { } this.educator = educator; stu.RaiseGrade(subject, points); } return true; public bool AddStudent(Student stu) } { public override string ToString() if (this.numStudentes==this.students.Length) { { int i; return false; string s = "class:" + this.level + this.number+"\n"; } s+= "educator "+this.educator; this.students[this.numStudentes] = stu; s += "students list:" + "\n"; this.numStudentes++; for (i = 0; i < this.numStudentes; i++) return true; {a s += this.students[i]; } return s; } '} שמורות ל'מבט לחלונות עיצוב תוכנה – טיפוס מורכב © כל הזכויות } 22 using System; Teacher המחלקה using System.Collections.Generic; using System.Text; namespace BookMabatPage10 { class Teacher { private string name; private string id; private int workingYears; private bool hasDiploma; private int numSubjects; private string[] subjects; public Teacher (string name, string id,int workingYears,bool hasDiploma,string firstSubject,int maxSubjects) { this.name = name; this.id = id; this.workingYears = workingYears; this.hasDiploma = hasDiploma; this.subjects = new string[maxSubjects]; this.subjects[0] = firstSubject; this.numSubjects = 1; } public void IncrementWorkingYears() { this.workingYears++; } public bool AddSubject(string subject) { if( this.numSubjects==this.subjects.Length) { return false; } this.subjects[this.numSubjects] = subject; this.numSubjects++; return true; } public bool TeachingSubject(string subject) { int i; s += "working years:" + this.workingYears + " has for (i = 0; i < this.numSubjects; i++) Diploma:" + this.hasDiploma + "\n"; { s += "subects:"; if (this.subjects[i] == subject) for (i = 0; i < this.numSubjects; i++) { { return true; s+=this.subjects[i]+" "; } } } s += "\n"; return false; return s; } } public override string ToString() } { } string s = ""; int i; s += "name:" + this.name + "," + "id:" + this.id +"\n" 23 'כל הזכויות שמורות ל'מבט לחלונות © עיצוב תוכנה – טיפוס מורכב כתוב פעולה תרגילים לטיפוס המורכב כיתה :פעולות תרגיל :1הגדרת פעולה בונה נוספת בטיפוס כיתה בהנחה שבטיפוס Teacherיש פעולה בונה שהחתימה שלהTeacher(string name, string id) : המקבלת שם ו-ת.ז .של מורה .כתוב פעולה בונה בטיפוס StudentClassהמקבלת כפרמטרים את: השכבה של הכיתה ,מספר הכיתה ,מספר התלמידים בכיתה ,שם המחנך של הכיתה ות.ז .של המחנך. הפעולה תאתחל בהתאמה את התכונות :שכבה ,מספר כיתה ,מספר תלמידים בכיתה ומחנך הכיתה. תרגיל :2הגדרת פעולה בונה מעתיקה הגדר במחלקה StudentClassפעולה בונה מעתיקה. שים :הפעולה מקבלת עצם מטיפוס .StudentClass תרגיל :3הגדרת פעולה מאחזרת בטיפוס כיתה nבמערך nומחזירה את התלמיד שמיקומו הגדר בטיפוס כיתה פעולה המקבלת מספר שלם התלמידים .הנח כי המספר nתקין ובטווח של מספר התלמידים בכיתה .שים לב שהפעולה מחזירה ערך מטיפוס תלמיד. תרגיל :4הגדרת פעולה קובעת בטיפוס כיתה חושבים הגדר בטיפוס כיתה פעולה המקבלת מספר שלם nותלמיד stuו קובעת את התלמיד להיות במקום n במערך התלמידים .הנח כי המספר nתקין ובטווח של מספר התלמידים בכיתה. רגע.. שאלה למחשבה :אם במקום nבמערך התלמידים כבר נמצא תלמיד (עצם מטיפוס )Student מה קורה לו? תרגיל :5הגדרה של פעולה בטיפוס כיתה המקבלת עצם כפרמטר הגדר בטיפוס כיתה פעולה המקבלת עצם מטיפוס מורה ובודקת האם הוא המחנך של הכיתה .אם כן תחזיר הפעולה אמת ,ואם לא תחזיר שקר. תרגיל :6הגדרת פעולה בטיפוס כיתה – המחזירה מערך תלמידים בטיפוס כיתה הוגדרה הפעולה )( BestInClassאשר מחזירה את התלמיד המצטיין בכיתה .התלמיד המצטיין הוא התלמיד שהממוצע שלו הגבוה ביותר .מה קורה אם יש מספר תלמידים בעלי אותו ממוצע? בפעולה שהוגדרה בגוף הפרק יוחזר התלמיד הראשון שימצא .איננו רוצים להסתפק בהגדרת פעולה זו מאחר ואינה מתאימה למציאות .כדי שנוכל להתאים פעולה זו למצב בו יש יותר ממצטיין אחד ,על הפעולה להחזיר מערך של תלמידים מצטיינים .כלומר מערך שיהיו בו כל התלמידים שיש להם את הממוצע הגבוה ביותר .כתוב פעולה )( BestsInClassהמחזירה מערך ובו התלמידים בעלי הממוצע הגבוה ביותר .שים :מה יהיה גודל המערך המוחזר? איך נדע כמה תלמידים יש בו? 24 עיצוב תוכנה – טיפוס מורכב © כל הזכויות שמורות ל'מבט לחלונות' דוגמה פתורה דוגמה פתורה :2הטיפוס דיסק פתח את פרוייקט הדיסק על-פי כל השלבים שהוצגו בפרק זה: דיאגרמת המחלקות המשתתפות בפרויקט; תיאור הטיפוסים בטבלה (הטיפוס שיר והטיפוס דיסק) מימוש במחלקות השונות ,וכיו"ב פתרון הפרויקט כולל שלושה טיפוסים :הטיפוס שיר הממומש במחלקה Songשהוצג בפרק 6בספר יסודות חלק ב ,הטיפוס המורכב דיסק הממומש במחלקה Discשתפותח כאן ,והמחלקה הראשית TestDisc שתפותח כאן. דיאגרמת המחלקות שמשתתפות בפרויקט זה היא: Song Disc TestDisc תיאור הטיפוס שיר הטיפוס שיר ( )Songמאפיין שירים ומתייחס אל שלוש תכונות :שם השיר ,שם המבצע ואורך השיר בשניות .ניתן כמובן להוסיף תכונות נוספות .האיור שלהלן מתאר את הטיפוס שיר וכולל הרחבה בסיווג הפעולות .כל הפעולות המופיעות באיור יופיעו בהגדרת המחלקה המממשת את הטיפוס: הטיפוס שיר תכונות שם השיר שם המבצע אורך השיר בשניות פעולות בונות שיר (_שם_ ,מבצע_ ,אורך) שיר ( ) { פעולה בונה הקולטת ערכים לתכונות } מאחזרות אחזר שם שיר ( ) אחזר שם מבצע ( ) אחזר אורך ( ) קובעות קבע שם שיר (_שם) 1 קבע שם מבצע ( _מבצע)1 קבע אורך (_אורך) 1 חישוביות הגדל אורך שיר ב (_מספר_שניות) הקטן אורך שיר ב (_מספר_שניות) סיווג אורך () { קצר -קטן מ 2 -דקות, ארוך -ארוך מ 4 -דקות, ממוצע – אחרת } הדפס פרטי שיר() עיצוב תוכנה – טיפוס מורכב © כל הזכויות שמורות ל'מבט לחלונות' 25 using System; Song מימוש המחלקה class Song { private string name; // Name of song private string performer; // Name of the Performer of the song תכונות private int length; // Length of song in seconds public Song(string name, string performer, int length) { this.name = name; this.performer = performer; this.Length = length; } public Song() { } public string GetName() { return name; } public string GetPerformer() { return performer; } public int GetLength() { return length; } public void SetName(string name) { this.name = name; } public void SetPerformer(string performer) { this.performer = performer; } public void SetLength(int length) { this.Length = length; } / -* הפעולה מגדילה את אורך השיר בsec* שניות/ public void IncreaseLength(int sec) { Length = Length + sec; } /* שניותsec -* הפעולה מקטינה את אורך השיר ב/ public void DecreaseLength(int sec) { Length = Length - sec; 'כל הזכויות שמורות ל'מבט לחלונות פעולות בונות פעולות מאחזרות פעולות קובעות פעולות חישוביות © 26 עיצוב תוכנה – טיפוס מורכב } / * * הפעולה מחזירה מחרוזת שהיא הקטגוריה של אורך השיר * ממוצע- אחרת, דקות – ארוך4 אם אורכו מעל, דקות – קצר2 * אם אורכו עד/ public string Category() { if (Length< 2*60) return "short"; else if (Length > 4*60) return "long"; else return "average"; } /* * הפעולה מדפיסה את תכונות השיר/ public void DisplaySongDetails() { Console.WriteLine("The song name is: " + name); Console.WriteLine("The preformer is: " + performer); Console.WriteLine("The song length in seconds is: " + length); } } תיאור הטיפוס דיסק - שלהלן (בחלק מתרשימי הUML -) מאפיין דיסק של שירים ומתואר בתרשים הDisc( הטיפוס דיסק :) שמוצגים בספר יש עמודה נוספת לצורך תיעוד סוגי הפעולות המוגדרותUML public Disc(string n, Song[] s) public Disc() public string GetName() public Song[] GetSongs() public void SetName(string name) public void SetSongs(Song[] songs) public void SetSong(int index, Song newSong) public Song GetSong(int index) public void SetSong(int index, Song newSong) public int DiscLength() public double AverageSongLength() public int MaxSongLength() public string NameOfLongestSong() public int NumberOfSongsInCategory(string c) public void DisplayDiscDetails() 27 'כל הזכויות שמורות ל'מבט לחלונות © עיצוב תוכנה – טיפוס מורכב בונות מאחזרות קובעות חישוביות פעולות עיין באתר אינטרנט הסבר הפתרון - - - - המימוש המלא של הטיפוס המורכב דיסק באתר האינטרנט בכתובת www.mabatl.co.il בקטגוריה :אתרים מלווי ספרים לחץ על בחר ב 'פרויקט דיסק-פרק '1 הסבר הקוד (שמוצג באתר): התכונה מערך שירים היא תכונה ככל התכונות האחרות ,ולכן גם עבורה מוגדרות פעולה קובעת SetSongsהמקבלת מערך שירים ומאתחלת את התכונה ,ופעולה מאחזרת GetSongsהמחזירה את התכונה שהיא מערך השירים. Discולכן אין צורך שיקבלו הפעולות המוגדרות בטיפוס הן פעולות שיופעלו על עצם מטיפוס כפרמטר את הדיסק או איזו שהיא תכונה שלו. הפעולה המחזירה את מספר השירים לפי קטגוריה ),NumberOfSongsInCategory(string c מקבלת כפרמטר מחרוזת ובה הקטגוריה הנדרשת – קטגוריה זו אינה תכונה של הדיסק או של אחד משיריו ,לכן היא מתקבלת כפרמטר. בכל הפעולות החישוביות יש התייחסות אל התכונה songsשהיא מערך של שירים .כאשר יש פניה אל ] ,songs[iיש פניה אל עצם מטיפוס Songועליו ניתן להפעיל פעולות המוגדרות בטיפוס .Song למשל.GetLength() : מתוך גוף הפעולה המחזירה את מספר השירים לפי קטגוריה ,נסביר את ההוראה: )if (songs[i].Category()==c ;count++ על השיר הנמצא במקום iבמערך השירים ,songsמופעלת הפעולה )( .Categoryפעולה זו מוגדרת בטיפוס Songומחזירה מחרוזת ובה הקטגוריה של השיר. מימוש המחלקה הראשית הפעולה הראשית במחלקה הראשית TestDiscמממשת את האלגוריתם הבא: )1בנה עצם חדש מטיפוס Diskוהשם אותו במשתנה .d )2חשב את האורך הכולל של הדיסק dע"י הפעולה )( DiscLengthוהשם את התוצאה במשתנה השלם .totalLength )3הדפס את אורך הדיסק מתוך המשתנה .totalLength )4חשב והדפס את הממוצע של אורך שיר בדיסק dע"י הפעולה )(.AverageSongLength )5חשב והדפס את שם השיר הארוך ביותר בדיסק dע"י הפעולה )(.NameOfLongestSong )6חשב והדפס את מספר השירים ה"קצרים" ע"י הפעולה )".NumberOfSongsInCategory("short 28 עיצוב תוכנה – טיפוס מורכב © כל הזכויות שמורות ל'מבט לחלונות' class TestDisc { // הפעולה הראשית public static void Main(string[] args) { string songName, performer; int length; Console.WriteLine("Enter disc name : "); string name = Console.ReadLine(); Console.WriteLine("Enter number of songs on disc: "); Song[] songs = new Song[int.Parse(Console.ReadLine())]; for ( int i=0 ; i<songs.Length ; i++ ) { Console.WriteLine("Enter song no. "+i+" name : "); songName = Console.ReadLine(); Console.WriteLine("Enter song no. "+i+" performer : "); performer = Console.ReadLine(); Console.WriteLine("Enter song no. "+i+" length : "); length = int.Parse(Console.ReadLine()); songs[i] = new Song(songName, performer,length); } Disc d = new Disc(name, songs); int totalLength = d.DiscLength(); Console.WriteLine("The disc total length is : " + totalLength ); Console.WriteLine ("The average song length is: " + d.AverageSongLength()); Console.WriteLine ("The longest song is: " + d.NameOfLongestSong()); Console.WriteLine ("The number of short songs is: " + d.NumberOfSongsInCategory("short")); } } באותו אופןDisc בפעולה הראשית נבנה עצם מן הטיפוס המורכב:הסבר גוף הפעולה הראשית אפשר להפעיל אתDisc שהוא מטיפוסd על העצם.Song בו נבנו עצמים מטיפוס פשוט כדוגמת .הפעולות המוגדרות בטיפוס שלו הסבר הפתרון על עצמיםToString הפעולה :?האם ניתן פשוט להדפיס את פרטי הדיסק כך 29 'כל הזכויות שמורות ל'מבט לחלונות © עיצוב תוכנה – טיפוס מורכב חושבים . המדפיסה את כל התכונות של הדיסקDisplayDiscDetails() הוגדרה הפעולהDisc במחלקה :הפעלה שלה בתכנית הראשית תהיה למשל Console.WriteLine ("The disc details: "); ..רגע d.DisplayDiscDetails(); Console.WriteLine (d); הסבר הפתרון הדפסה כזו תביא להפעלה אוטומטית של הפעולה ToStringעל הדיסק .dכאשר פעולה זו מופעלת על עצם ,הפעולה ToStringתחזיר למשל את המחרוזת הבאהDisc : במחרוזת זו מופיע שם המחלקה .מחרוזת זו אינה המחרוזת בה אנו מעוניינים הכוללת את כל ערכי התכונות של הדיסק .אם אנו מעוניינים בהדפסה "אוטומטית" כזו עלינו להגדיר מחדש את הפעולה ToStringעבור המחלקה שלנו .ההבדל יהיה בכך שכל הפרטים הנדרשים להופיע בפלט ישורשרו למחרוזת אחת שתוחזר ע"י הפעולה ToStringואז הוראת הפלט שהוצגה לעיל אמנם תתן את הרצוי. כלומר בכל פעם שנבקש להדפיס עצם מטיפוס Discתופעל עליו הפעולה ToStringהמחזירה מחרוזת המתארת אותו והיא זו שתודפס .נגדיר את הפעולה באופן זה: */הפעולה מחזירה מחרוזת המכילה את פרטי הדיסק */ )(public override string ToString { ;"string discDetails = "The disc details:"+"\n"+"The disc name is: "+name +"\n ) for ( int i = 0 ; i < songs.Length ; i++ { ;"discDetails = discDetails + "Song number " + (i+1) + " : " + songs[i] + "\n } ;return discDetails } המחרוזת המוחזרת מאותחל תחילה להיות המחרוזת " ."The disc details:תת המחרוזת ""/n מסמנת ירידה בשורה תוך כדי ההדפסה ולאחריה המחרוזת " "The disc name is:משורשרת לשם הדיסק ושוב ירידה של שורה בהדפסה .לאחר מכן משורשרים פרטי כל השירים בדיסק ,אחרי כל שיר יש ירידה בשורה .המחרוזת הכוללת בה כלולים כל פרטי הדיסק יחד עם הנחיות הדפסה מוחזרת. שים :כדי שפעולה זו תפעל כראוי יש צורך בהתאמה להגדיר פעולה ToStringבמחלקה .Song כתוב מחלקה תרגילים לטיפוס מורכב... : תרגיל :7הגדרת פעולה בטיפוס דיסק – מספר השירים בכל קטגוריה הגדר בטיפוס Discפעולה המחזירה מערך מונים בן 3תאים .בתא הראשון יהיה מספר השירים הקצרים בדיסק ,בתא השני יהיה מספר השירים באורך ממוצע בדיסק ,בתא השלישי יהיה מספר TestDiscלבדיקת השירים הארוכים בדיסק .הוסף הוראה מתאימה בפעולה הראשית במחלקה הפעולה. תרגיל :8שינוי פעולות בטיפוס דיסק – החזרת השיר הארוך בטיפוס Discהוגדרו שתי פעולות המבצעות מבחינה אלגוריתמית את אותה המשימה .הפעולה )(NameOfLongestSong )( MaxSongLengthמחזירה את אורך השיר הארוך ביותר .הפעולה מחזירה את שם השיר הארוך ביותר .במקום שתי הפעולות האלה הגדר פעולה )(TheLongestSong המחזירה את השיר הארוך ביותר בדיסק. הוסף את ההוראות הבאות בפעולה הראשית במחלקה :TestDisc )1מצא את השיר הארוך ביותר בדיסק על ידי הפעולה )( TheLongestSongוהשם את השיר ב- .maxSong )2הדפס את שם השיר maxSongואת אורכו. 30 עיצוב תוכנה – טיפוס מורכב © כל הזכויות שמורות ל'מבט לחלונות' בפרק זה הודגם שימוש במערך של עצמים שהוא תכונה של עצם מטיפוס מורכב (למשל ,מערך שירים בטיפוס דיסק) .בעבר (בספר יסודות מדעי המחשב ,חלק ב ,פרק )7הודגם שימוש במערך של עצמים ששימש כמשתנה בתכנית הראשית. נשאלת השאלה :האם יש הבדל בדרך בה אנו משתמשים במערך בשני ההקשרים? התשובה היא :לא. הטיפול במערך של עצמים הוא זהה בכל מקרה .לא חשוב אם מערך העצמים הוא משתנה מקומי (בפעולה הראשית או בכל פעולה אחרת) או תכונה של עצם. למרות עקרון זה יש הבדלים הניכרים במרכיבים הבאים: ( )1בדרך הפנייה אל משתנה או אל תכונה. ( )2בדרך הגדרת הפעולות – האם הן פעולות סטטיות במחלקה ראשית אשר מקבלות את המערך כפרמטר ,או שהן פעולות המוגדרות בטיפוס המייצג ישות ,ואז הן לא תהיינה סטטיות ,וגם לא תקבלנה את המערך כפרמטר .פעולות אלו תופעלנה על עצם שהמערך הוא אחת התכונות שלו ולכן אין צורך בפרמטר. דוגמה לשימוש במערך עצמים כמשתנה או כתכונה חלק מן הפעולות שהוגדרו בטיפוס דיסק בפרק זה הוגדרו בספר יסודות חלק ב בפרק :7מערך של עצמים ,דוגמה .2התייחסו ת למשתנה שהוא מערך של עצמים אשר הוגדר למשל בתכנית הראשית .Discהאלגוריתמים ,SongProgram2זהה לטיפול במערך של עצמים שהוא תכונה בטיפוס המתייחסים למערך השירים הם אותם אלגוריתמים אך יש הבדלים בדרך הגישה אל מערך השירים. נסתכל ונשווה למשל את הפעולה המחשבת את ממוצע אורכי השירים הנמצאים במערך שירים במחלקה ,SongProgram2אל הפעולה המחשבת את ממוצע אורכי השירים של השירים בדיסק במחלקה .Discברור כי האלגוריתם לביצוע הפעולה הוא זהה .בכל מקרה לצורך חישוב הערך המוחזר ,יש לצבור את אורכי השירים ולחלק במספר השירים .ההבדלים באים לידי ביטוי בכותרת הפעולה ,בשם המערך המיוחס בגוף הפעולה ,ובדרך זימון הפעולה. פעולה סטטית שהוגדרה במחלקה ראשית כותרת הפעולה: public static double )AverageSongLength(Song[] s הפעולה היא סטטית כי לא תופעל על עצם. הפעולה מקבלת את מערך השירים כפרמטרכדי שתוכל להתייחס אל ערכיו. פעולה פנימית שהוגדרה במחלקה Disc כותרת הפעולה: ()public double AverageSongLength הפעולה אינה סטטית כי היא תופעל על עצם. הפעולה לא מקבלת את מערך השירים כפרמטר כי מערךהשירים הוא תכונה של העצם עליו תופעל הפעולה. עיצוב תוכנה – טיפוס מורכב © כל הזכויות שמורות ל'מבט לחלונות' 31 { :גוף הפעולה int sum = 0; for ( int i = 0 ; i<this.songs.Length ; i++ ) { sum = sum+ this.songs[i].GetLength(); } return (double)sum/this.songs.Length; } int sum = 0; for ( int i = 0 ; i<s.Length ; i++) { sum = sum+ s[i].GetLength(); } return (double)sum/s.Length; } . האלגוריתם בגוף הפעולה זהה הפעולה מתייחסת אל המערך שהוא התכונה של העצם עליו.songs על פי שם התכונה,הופעלה :גוף הפעולה } . האלגוריתם בגוף הפעולה זהה הפעולה מתייחסת אל המערך שהתקבל.s כפרמטר :זימון הפעולה :זימון הפעולה public static void Main(string[] args) public static void Main(string[] args) { string songName, performer; { int length; Song[] songs= InitialSongArray(); Console.WriteLine("Enter disc name : "); Console.WriteLine("The average string name = Console.ReadLine(); song length is: Console.WriteLine("Enter songs no."); "+AverageSongLength(songs)); songs=newSong[int.Parse(Console.ReadLine())]; } for ( int i=0 ; i<songs.Length ; i++ ) הפעולה הראשית מוגדרת במחלקה{ .SongProgram2 Console.WriteLine("Enter song name: "); הפעולה הראשית מוגדרת באותה מחלקה בהSongName = Console.ReadLine(); Console.WriteLine("Enter song .AverageSongLength מוגדרת הפעולה performer: "); שם מערך השירים שהוא משתנה של הפעולהperformer = Console.ReadLine(); .songs הראשית הוא Console.WriteLine("Enter song length: "); מערך השירים מאותחל על ידי שירים בעזרתlength = int.Parse(Console.ReadLine()); שאף היא פעולהInitialSongArray() הפעולה songs[i] = new Song(songName, .SongProgram2 סטטית במחלקה performer,length); מועבר כפרמטר לפעולהsongs המערך} כדי לחשב את ממוצעAverageSongLength Disc d = new Disc(name, songs); .אורכי השירים הנמצאים בו Console.WriteLine ("The average song length is: "+ d.AverageSongLength()); } בעוד הפעולה.TestDisc הפעולה הראשית מוגדרת במחלקה.Disc מוגדרת בתוך הטיפוסAverageSongLength ולכן אינו מופיע,d מערך השירים הוא תכונה של הדיסק.במפורש בגוף הפעולה הראשית מערך השירים מאותחל על ידי שירים בעזרת הפעולה הבונה. Disc(name, songs) :של דיסק AverageSongLength אין צורך להעביר אף פרמטר לפעולה הפעולה.d כדי לחשב את ממוצע אורכי השירים בדיסק . ומערך השירים הוא תכונה שלו,מופעלת על הדיסק עצמו 'כל הזכויות שמורות ל'מבט לחלונות © 32 עיצוב תוכנה – טיפוס מורכב עד כה התייחסנו אל תכונות המאפיינות עצמים .לפעמים יש צורך בתכונה המשותפת לכל העצמים במחלקה .תכונה של מחלקה היא תכונה המוגדרת כ staticושעבורה מוקצה זיכרון רק פעם אחת ואין הקצאת זיכרון נפרדת עבור כל עצם שנוצר כמו לגבי התכונות שהכרנו עד כה .הערך שלה ברגע מסוים זהה לגבי כל העצמים .לתכונה זו ניתן לפנות דרך העצמים או דרך המחלקה .כל שינוי בתכונה גם אם נעשה על ידי עצם אחד של המחלקה חל למעשה לגבי כולם – כי יש לו שטח זיכרון אחד. דוגמה :שיוך מספר סידורי לכל עצם שנוצר מן המחלקה נניח שאנו מפתחים מבחן ממוחשב .כל נבחן מקליד את שמו ומקבל מספר נבחן שהוא מספר סידורי עוקב ביחס לכל הנבחנים .נסתפק בהגדרת התכונות הבאה עבור כל תלמיד :שם ,מספר נבחן והמבחן עצמו .כדי שכל נבחן יקבל מספר אחר ייחוד י לו וגם עוקב לנבחן הקודם ,יש להגדיר תכונה משותפת תלמיד-נבחן תקדם את מונה הנבחנים לכל הנבחנים ,כתכונה סטטית .כל בניה של עצם מטיפוס מספר-נבחן של התלמיד .להלן חלקים מקוד המחלקות הכללי ותציב את ערך המונה לתכונה בפרויקט ותוצאות הרצה של הפעולה הראשית. – testCounterתכונה של מחלקה ומוגדרת כstatic - קידום התכונה של המחלקה testCounter והשמת ערכה לתכונה numהמיוחסת לעצם שנבנה פעולה מאחזרת לתכונה חייבת להיות static כי היא מתייחסת לתכונה שהיא static ;using System public class TestStudent { ;private static int testCounter = 0 ;private string name ;private int num )TestStudent(string name { ;this.name = name ;testCounter ++ ;this.num = testCounter } )( public static int GetTestCounter { ;return testCounter } )(public override string ToString { ;return "name = " + name + " --- " + num } } עיצוב תוכנה – טיפוס מורכב © כל הזכויות שמורות ל'מבט לחלונות' 33 public class MainTest { )(public static void main { קבלת ערך התכונה ;)"TestStudent s1 = new TestStudent("aaa testCounterדרך המחלקה ;)"TestStudent s2 = new TestStudent("bbb בלבד לא ניתן דרך עצם כי ;)"TestStudent s3 = new TestStudent("ccc הוא שייך רק למחלקה. ;)Console.WriteLine(s1 ;)Console.WriteLine(s2 ;)Console.WriteLine(s3 ;))(Console.WriteLine("testCounter value: " + TestStudent.GetTestCounter } } הפלט המתקבל הוא: name = aaa --- 1 name = bbb --- 2 name = ccc --- 3 testCounter value: 3 כאשר ניגשים לפתרון בעיה בתכנות מונחה עצמים יש לזהות תחילה את העצמים השותפים לפתרון הבעיה .העצמים הם הגורם המרכזי – בעזרתם מתבצעות פעולות – ולכן קוראים לסגנון תכנות זה תכנות מונחה עצמים .בדרך כלל בפתרון בעיה יש שימוש במספר עצמים בעלי אותם מאפיינים ולכן מגדירים טיפוס .טיפוס משמש תבנית ליצירת עצמים שלכל אחד מהם יש את אותן התכונות ,ועל כל אחד מהם ניתן להפעיל את אותן הפעולות .אחרי אפיון הטיפוסים ניתן לפתח כל טיפוס כמחלקה בשפת התכנות .הפיתוח הוא מודולארי ומתייחס רק לממשק הטיפוסים האחרים .כאשר טיפוס אחד משתמש בטיפוס אחר ,הדבר יכול לבוא לידי ביטוי בטיפוס של :תכונות ,פרמטרים ,משתנים מקומיים ,או ערכים מוחזרים .אין צורך בפעולה מיוחדת כדי להגיד שטיפוס אחד משתמש בטיפוס אחר ומספיק שהוא מופיע באחד ההקשרים שפורטו .על כל עצם מטיפוס ,המופיע בטיפוס אחר ניתן להפעיל את כל הפעולות המוגדרות בטיפוס שלו .האלגוריתם הראשי לפתרון הבעיה ייכת ב במחלקה ראשית ,מחלקה שאינה מייצגת עצמים ,אלא מנהלת את האלגוריתם לפתרון הבעיה הרצויה. להלן מתכון לפתרון בעיה בתכנות מונחה עצמים: ( )1זיהוי העצמים הנדרשים לפתרון הבעיה. ( )2אפיון הטיפוסים של העצמים (טיפוסים המייצגים ישויות). ( )3פיתוח כל טיפוס בנפרד כמחלקה בשפת התכנות (תכונות ,פעולות). ( )4פיתוח המחלקה הראשית ובה הפעולה הראשית שבה מופיע האלגוריתם הראשי לפתרון הבעיה. כאשר בעיה מוצגת באופן מילולי בעברית ,דרך אפשרית היא לנתח אותה מבחינה לשונית במטרה לזהות את הישויות ואת הפעולות הנדרשות עבורם .הזיהוי הלשוני הוא לפי הכללים הבאים :שמות עצם עשויים לציין עצמים (שיוכללו לטיפוסים) ופעלים עשויים לציין פעולות. 34 עיצוב תוכנה – טיפוס מורכב © כל הזכויות שמורות ל'מבט לחלונות' כתוב מחלקה תרגילים לטיפוס מורכב :כתוב מחלקה... שים :בכל מקרה בו יש לפתח מחלקה ,הבסיס לפיתוח כולל :הגדרת תכונות ,הגדרת פעולות בונות ,והגדרת פעולות מאחזרות וקובעות לכל תכונה. תרגיל 9רכבות הטיפוס קטר ) (Engineמאופיין על-ידי מספר רישוי ושנת יצור. הטיפוס קרון-רכבת ) (Carriageמאופיין על-ידי מספר סידורי של הקרון ,ומספר הנוסעים שיכולים לנסוע בו .הטיפוס רכבת ) (Trainמאופיין על-ידי קטר ומערך של nקרונות ,מספר הקרונות שיש ברכבת בפועל ( nהוא מספר הקרונות המקסימלי שהרכבת יכולה להכיל) א .פתח מחלקה לכל אחד מהטיפוסים. ב .ממש את הפעולות החישוביות הבאות במחלקה רכבת: .1החלף את הקטר של הרכבת( .האם פעולה זו כבר הוגדרה לפני כן?) .2הוסף קרון לרכבת. .3החזר את מספר הנוסעים הכולל ברכבת. .4החזר את מספר הנוסעים הממוצע לקרון ברכבת. ג .פתח מחלקה ראשית הבונה רכבת ,מפעילה את הפעולות שמימשת בסעיף ב ומציגה את נתוני הרכבת. תרגיל :10הטיפוס משחק רובוטים פתח מחלקה משחק-רובוטים RobotGameשבה שתי תכונות :מספר המשבצות בלוח המשחק ומערך הרובוטים המשתתפים במשחק .המחלקה תשתמש במחלקה Robotותוגדרנה בה פעולות מתאימות לניהול משחק הרובוטים כפי שתואר בספר יסודות ,חלק ב בעמוד .146הרובוטים יכולים לנוע קדימה או אחורה .רובוט אשר חורג בצעדיו מגבולות לוח המשחק יוצא מן המשחק. המאפיינים הבסיסיים של כל רובוט הם: תכונות :צבע ,מספר משבצת עליו הוא עומד ,האם נמצא במשחק?. פעולות חישוביות :צעד קדימה -הרובוט נע משבצת אחת קדימה ,צעד אחורה -הרובוט נע משבצת אחת לאחור ,קפוץ קדימה ב n -צעדים ,קפוץ אחורה ב n -צעדים. על הפעולה הראשית לנהל בין הרובוטים משחק אקראי .כללי המשחק הם :הרובוטים מתחילים 4אפשרויות) .אם במשבצת מספר .10בכל שלב עבור כל רובוט מוגרלת פעולת ההתקדמות שלו ( הוגרלה פעולת קפיצה יש להגריל גם את ערך הקפיצה מ .1-6הרובוט הראשון שנעמד על המשבצת 100הוא המנצח .אם רובוט מגיע למשבצת עליה נמצא רובוט אחר הוא מוציא את הרובוט השני מן המשחק. הגדר פעולה נוספת המחזירה את הרובוט הנמצא על משבצת שמספרה הוא הגדול ביותר .פתח מחלקה ראשית בה יוגדר עצם מטיפוס משחק-רובוטים ,ותזומן הפעולה לניהול המשחק. עיצוב תוכנה – טיפוס מורכב © כל הזכויות שמורות ל'מבט לחלונות' 35 תרגיל :11הטיפוס מרוץ מכוניות פתח מחלקה מרוץ-מכוניות CarRaceשבה שתי תכונות :מספר המכוניות המשתתפות במרוץ ומערך המכוניות המשתתפות במרוץ .המחלקה תשתמש במחלקה ( Carאפשר להוריד את המחלקה מאתר האינטרנט באתר מלווה ספר בגאווה) .ותוגדרנה בה פעולות מתאימות לניהול המרוץ כפי שתואר בספר יסודות ,חלק ב ,תרגיל 3בעמוד :157עם פתיחת המרוץ כל המכוניות מזנקות בו זמנית .במהלך המרוץ המכונית מאטה או מאיצה לחלופין .מדמה המרוץ שלנו יגריל עבור כל מכונית בכל שלב מספר שלם בתחום של .1-4קוד – 1המכונית מגבירה מהירותה ב 10 -קמ"ש (בתנאי שלא עברה את המהירות המקסימלית שלה) ,קוד – 2המכונית מאטה את מהירותה ב 10 -קמ"ש (בתנאי שלא ירדה ממהירות 0קמ"ש) ,קוד – 3המכונית מאטה את מהירותה ב 20 -קמ"ש (בתנאי שלא ירדה ממהירות 0קמ"ש) ,קוד – 4ארעה תקלה או התנגשות – המכונית פורשת מן המרוץ .המכונית שחוצה ראשונה את קו הסיום היא המנצחת במרוץ. הגדר פעולה נוספת המחזירה את המכונית המובילה במרוץ .פתח מחלקה ראשית בה יוגדר עצם מטיפוס מרוץ-מכוניות ,ותזומן הפעולה לניהול המרוץ. הרחבה :נניח שברצוננו לעקוב אחר התנהלות כל מכונית המשתתפת במרוץ לאורך המרוץ .לצורך כך יש לדעת בכל שלב כמה פעמים המכונית שינתה מהירות (האטה או האיצה) .תכנן את השינויים הנדרשים .עבור כל תוספת שתאפשר את פתרון הבעיה המורחבת ,שים דגש על זיהוי המחלקה המתאימה להגדיר בה את התוספת. תרגיל :12חייל מילואים א .הגדר מחלקה תאריך ) *(MyDateשמאפייניה הם יום ,חודש ושנה ,המכילה פעולה בונה לפי פרמטרים ,פעולות קובעות ,פעולות מאחזרות ,ואת הפעולות החישוביות הבאות: .1פעולה המחזירה מחרוזת המתארת את התאריך ( .(ToString .2פעולה המחזירה את היום העוקב ליום עליו מופעלת הפעולה. .3פעולה המחזירה את היום הקודם ליום עליו מופעלת הפעולה. .4פעולה המקבלת תאריך ומחזירה את ההפרש בימים בין התאריך עליו מופעלת הפעולה ובין התאריך שהתקבל כפרמטר. ב .הטיפוס חייל מילואים ) (Soldierמאופיין על-ידי מספר אישי ,דרגה ,תאריך לידה ,תאריך גיוס לשרות סדיר ותאריך שחרור משרות סדיר .בנה מחלקה המגדירה את תכונות הטיפוס ,פעולה בונה ,פעולות קובעות ,פעולות מאחזרות ואת הפעולה .ToStringכמו-כן תכיל המחלקה פעולה trueאם חייל מילואים צריך להשתחרר בוליאנית המקבלת את התאריך של היום ומחזירה ממילואים או לא .חייל מילואים משתחרר כאשר הוא מגיע לגיל .40 ג .כתוב מחלקה ראשית הבונה בפעולה הראשית מערך של Nחיילי מילואים ומזמנת את הפעולות הסטטיות הבאות: )1פעולה המדפיסה לכל חייל מילואים את משך תקופת השרות הסדיר שלו בימים. )2פעולה המקבלת את התאריך של יום מסוים ,מוציאה ממערך החיילים את חיילי המילואים שצריכים להשתחרר ,ומחזירה את מספר החיילים המעודכן שנשארו במערך .יש להקפיד שאברי המערך יופיעו במערך ברצף. )3פעולה המקבלת את מערך החיילים ואת מספר החיילים במערך ומדפיסה את פרטיהם. 36 עיצוב תוכנה – טיפוס מורכב © כל הזכויות שמורות ל'מבט לחלונות' תרגיל :13תעודת זהות תעודת זהות של קטין מאופיינת על-ידי מספר תעודת-זהות ,שם פרטי ,שם משפחה ,תאריך לידה, ארץ לידה ,ולאום .תעודת זהות של מבוגר מאופיינת על-ידי מספר תעודת-זהות ,שם פרטי ,שם משפחה ,תאריך לידה ,ארץ לידה ורשימת תעודות זהות של ילדיו הקטינים – עד .15 א .בנה מחלקות לייצוג הטיפוסים הדרושים .חשוב ,האם ניתן להשתמש באותו טיפוס עבור תעודת זהות של קטין ועבור תעודת זהות של מבוגר? השתמש במחלקה המייצגת את הטיפוס תאריך) (MyDateאותה פיתחת בתרגיל .14 ב .הוסף את הפעולות הבאות למחלקות המתאימות .ציין לכל פעולה לאיזו מחלקה היא שייכת ,ותן .1הוסף-ילד-להורה דוגמה לזימון הפעולה. .2הוצא-קטין-שהפך-מבוגר-מתעודת-הורה. .3החזר-מספר-ילדים-משותפים-לשני-מבוגרים ג .כתוב פעולה ראשית הבונה עצמים של 10קטינים ,ומערך של 5מבוגרים .הפעולה משייכת את הקטינים להוריהם ומציגה כפלט את זוגות המבוגרים שיש להם ילדים משותפים .כל זוג שיש לו ילדים משותפים יופיע בפלט פעם אחת. תרגיל :14בניינים חדר ) (Roomהוא טיפוס נתונים המאופיין על-ידי סוג החדר(למשל :סלון ,חדר-שינה ,חדר-ילדים, חדר-עבודה ,מטבח ,אמבטיה וכו') ,אורך החדר ורוחב החדר. דירה ) (Apartmentהוא טיפוס נתונים המאופיין על-ידי שם בעל הדירה ואוסף החדרים של הדירה – עד 10חדרים. בניין ) (Buildingהוא טיפוס נתונים המאופיין על-ידי כתובת הבניין והדירות המצויות בו – עד 100 דירות. א .הגדר במחלקה Roomאת תכונות הטיפוס חדרושתי פעולות בונות :פעולה בונה אחת המקבלת את ערכי התכונות כפרמטרים ופעולה בונה מעתיקה. ב .הוסף למחלקה Roomפעולה המחזירה את שטח החדר. ג .הגדר במחלקה Apartmentאת תכונות הטיפוס דירה וכן פעולה בונה. ד .הגדר במחלקה Buildingאת תכונות הטיפוס בניין .הנח כי מוגדר טיפוס כתובת ))Address הבנוי מ 3-תכונות.street, number, city : ה .הוסף את הפעולות הבאות .לכל פעולה ציין לאיזו מחלקה של טיפוס היא שייכת ,או למחלקה , )getפעולות הראשית .הנח כי בכל מחלקה של טיפוס קיימות פעולות מאחזרות (שם-תכונה קובעות שם-תכונה )setוהפעולה .ToString .1חישוב והדפסת השטח הכולל של דירה. .2החזרת קטגוריה של גודל הדירה -small :עבור דירה שגודלה עד (כולל) 70מ"רmedium , – עבור דירה שגודלה עד 110מ"ר וכולל – large ,עבור דירה שגודלה מעל 110מ"ר. .3הדפסת כתובת הבניין/ים שיש בו הכי הרבה דירות גדולות השייכות לקטגוריה ,largeוכן שמות בעלי דירות אלה. עיצוב תוכנה – טיפוס מורכב © כל הזכויות שמורות ל'מבט לחלונות' 37 תרגיל :15מגדל של קוביות מגדל-של- הטיפוס קובייה ) (Cubeמאופיין על-ידי אורך צלע של קובייה וצבע הקובייה .הטיפוס קוביות ) (CubesTowerמאופיין על-ידי מספר הקוביות המקסימלי שמגדל יכול להכיל ,מספר הקוביות שמגדל מסוים מכיל בפועל ואוסף הקוביות המונחות אחת-על השנייה. על הטיפוס מגדל-של-קוביות ) (CubesTowerמוגדרות הפעולות החישוביות הבאות: .1הוספת קובייה למגדל (אם המגדל אינו בתפוסתו המקסימלית). .2הסרת קובייה מראש המגדל (אם יש במגדל לפחות קובייה אחת). .3בדיקה האם צבע מסוים מופיע בקובייה במגדל. .4בדיקה האם המגדל ריק. .5בדיקה האם המגדל נמצא בתפוסתו המקסימלית. א .בנה מחלקה לטיפוס קובייה ) (Cubeהכוללת את תכונות הקובייה ,פעולה בונה ,פעולות קובעות, פעולות מאחזרות ,פעולה המחזירה מחרוזת המתארת את הקובייה ( ,)ToStringואת הפעולה Equalsהמחזירה אמת אם שתי קוביות זהות ,או שקר אחרת. ב .בנה מחלקה לטיפוס מגדל-של-קוביות ) (CubesTowerהכוללת את תכונות המגדל ,פעולה בונה, פעולות מאחזרות ,פעולות קובעות ,ToString ,את הפעולה Equalsהמחזירה אמת אם שני מגדלים זהים ,או שקר אחרת ואת הפעולות החישוביות שפורטו לעיל. ג .בנה מחלקה ראשית המכילה פעולה ראשית הבונה מגדל-של-קוביות שגודלו המקסימלי מתקבל -1הוספת כקלט .הפעולה הראשית תקלוט מהמשתמש את הפעולה אותה הוא רוצה לבצע: קובייה למגדל או -2הסרת קובייה מהמגדל ,ותפעיל אותה על המגדל .הקלט יסתיים כאשר ייקלט מספר פעולה 0או כאשר לא ניתן לבצע פעולה מסוימת .במקרה שלא ניתן לבצע פעולה מסוימת יש להדפיס הודעה מתאימה .לאחר כל פעולה יש להדפיס את המגדל. ד .מעוניינים להוסיף את הפעולה מגדל-צבעים-ייחודים .הפעולה תבנה מגדל חדש ממגדל נתון. במגדל החדש תופיע רק קובייה אחת מכל צבע שקיים במגדל הנתון .בסוף הפעולה המגדל הנתון יישאר ללא קוביות .הפעולה תחזיר את המגדל החדש .ממש את הפעולה בשני אופנים :הראשון – במחלקה מגדל-של-קוביות והשני – במחלקה הראשית .כתוב זימון לכל אחת מהפעולות. כתוב מחלקה פרויקטים מסכמים בתכנות מונחה עצמים תרגיל :16חניונים – תרגיל סיכום I תכנה חדשנית לניהול חניונים דרך האינטרנט של חברת "חנה וסע" מאפשרת למנוייה להזמין מקום חניה דרך האינטרנט לשעה מסוימת ,תוך ציון משך הזמן המשוער .ניתן להזמין מקומות חנייה רק לאותו יום ובשעה עגולה .בסופו של יום מתרוקנים כל החניונים .אדם שמזמין חניה מקבל תשובה המציינת אם ההזמנה ניתנת למימוש .אם הזמנה אכן ניתנת למימוש – נשמר לאותו אדם מקום חנייה מסוים בשעה הנדרשת .מקום החניה נשמר ללקוח בשעה זו ,כלומר הופך להיות מקום חניה תפוס. במקרה שהמנוי הזמין מקום חניה ולא הגיע לחניון ,המקום נשמר למשך שעה עבורה הוא מחויב בתשלום .במקרה שהמנוי מימש את הזמנתו – התשלום מתבצע בהתאם לזמן ההזמנה (ולא מזמן 38 עיצוב תוכנה – טיפוס מורכב © כל הזכויות שמורות ל'מבט לחלונות' ההגעה) .למימוש מערכת זו מוגדרים הטיפוסים :כתובת ,מנוי ,הזמנה ,חניון ,מערכת חניונים. להלן דיאגרמת תרשים לכל אחד מהטיפוסים .הנח כי לכל אחד מהטיפוסים קיימות פעולות בונות, קובעות מאחזרות והפעולה .ToString הטיפוס הטיפוס תכונות כתובת רחוב מטיפוס מחרוזת מספר מטיפוס שלם מטיפוס מחרוזת עיר תכונות מטיפוס מחרוזת שם מטיפוס מחרוזת ת.ז. כתובת מטיפוס כתובת סכום-לתשלום מטיפוס ממשי פעולות הוסף-תשלום(סכום-תשלום) ביצוע-תשלום הטיפוס הזמנה הטיפוס תכונות מספר-הזמנה מטיפוס שלם מנוי מטיפוס מנוי מספר-רכב מטיפוס מחרוזת מספר-חניון מטיפוס שלם שעת-התחלה-משוערת מטיפוס שלם מטיפוס שלם שעת-סיום-משוערת שעת-סיום מטיפוס ממשי מקום -חניה מטיפוס שלם סטטוס-ביצוע מטיפוס בוליאני פעולות בצע-הזמנה() החזר-סכום-לתשלום-עבור-הזמנה() הטיפוס מנוי חניון תכונות כתובת מטיפוס מחרוזת מטיפוס מחרוזת ת.ז. רשימת הזמנות מטיפוס מערך של הזמנה מערך-מקומות-חניה מטיפוס מערך בוליאני תעריף-שעת-חניה מטיפוס ממשי פעולות האם-הזמנה-ניתנת למימוש(מספר-הזמנה) הוסף-הזמנה(הזמנה) עדכן-מקומות-חניה-להזמנות (שעה-נוכחית) (שעה-נוכחית) בטל-הזמנות-שלא-מומשו שחרור-רכב (מספר-רכב ,שעה-נוכחית) החזר-סכום-לתשלום-עבור-חניה(מספר-הזמנה) מערכת חניונים תכונות מערך-מנויים מספר-מנויים מערך-חניונים פעולות הוסף-מנוי (מנוי) מחק-מנוי(מנוי) האם-מנוי-קיים(מנוי) מטיפוס מערך של מנוי מטיפוס שלם מטיפוס מערך של חניון א. ממש את הפעולה בצע-הזמנה() שבמחלקה הזמנה .הפעולה מתבצעת כאשר רכב מגיע לחניון. הפעולה מעדכנת את סטאטוס הביצוע של ההזמנה ל . true -כתוב הוראת זימון לפעולה וציין מאיזו מחלקה יתבצע זימון זה. ממש את הפעולה עדכן-מקומות-חניה-להזמנות(שעה-נוכחית) שבמחלקה חניון .הפעולה מעדכנת את מקומות החניה שהוזמנו לשעה-נוכחית זו להיות תפוסים .כתוב הוראת זימון לפעולה וציין מאיזו מחלקה יתבצע זימון זה. ג. ממש את הפעולה שחרור-רכב שבמחלקה חניון .הפעולה מעדכנת את מקום החניה של הרכב להיות פנוי ,מעדכנת את שעת הסיום ,ומוסיפה למנוי את הסכום לתשלום. ב. עיצוב תוכנה – טיפוס מורכב © כל הזכויות שמורות ל'מבט לחלונות' 39 ממש את הפעולה בטל-הזמנות-שלא-מומשו(_שעה-נוכחית) שבמחלקה חניון .הפעולה בודקת אלו הזמנות לא מומשו (אלה פעולות שעברה שעה מזמן ההתחלה המשוער ועדיין לא הגיעו) .הפעולה מפעילה על מכוניות שהזמנותיהן לא מומשו את הפעולה שחרור-רכב(מספר_רכב_ ,שעת_יציאה). במחלקה הראשית מוגדרת הפעולה קליטת-הזמנות .להלן אלגוריתם כללי לביצוע הליך זה: ד. ה. קליטת-הזמנות(_מערכת_חניונים) כל עוד יש הזמנות בצע: קלוט מספר ת.ז .של מנוי .אם המנוי לא קיים במאגר המנויים בנה עצם מטיפוס מנוי והוסףאותו למאגר המנויים. קלוט את פרטי ההזמנה ההתחלתיים :מספר-רכב ,שעת-התחלה-משוערת ,שעת-סיום-משוערת ומספר חניון .אם לא ידוע מספר החניון ,קלוט כתובת מבוקשת והפעל את הפעולה החזר-מספר-חניון-הקרוב-ביותר-לכתובת(_כתובת) הנמצאת בטיפוס מערכת-חניונים. בנה עצם מטיפוס הזמנה .אם ההזמנה ניתנת למימוש הוסף אותה לרשימת ההזמנות שלהחניון .הדפס הודעה מתאימה אם ההזמנה ניתנת למימוש או לא. ממש פעולה זו ב C#-וכן את הפעולות הדרושות כפי שפורטו לעיל. ו .הוסף למחלקה הראשית פעולה המדפיסה לכל חניון את מספר המקומות הפנויים. תרגיל :17טלפון סלולרי – תרגיל סיכום II 60 מאפייני טלפון סלולארי הם :מספר הטלפון ,שם בעל הטלפון ,תעודת זהות של בעל הטלפון, שיחות נכנסות אחרונות 60 ,שיחות יוצאות אחרונות 60 ,הודעות נכנסות אחרונות 60 ,הודעות יוצאות אחרונות ,וספר טלפונים בגודל של 200מספרים. שיחה נכנסת מאופיינת על-ידי :תאריך ,שעה ,מספר הטלפון ממנו התקבלה השיחה. שיחה יוצאת מאופיינת על-ידי :תאריך ,שעה ,מספר הטלפון אליו הופנתה השיחה. הודעה נכנסת מאופיינת על-ידי :תאריך ,שעה ,מספר הטלפון ממנו התקבלה ההודעה ותוכן ההודעה. הודעה יוצאת מאופיינת על-ידי :תאריך ,שעה ,מספר הטלפון אליו נשלחה ההודעה ותוכן ההודעה. איש קשר בספר טלפונים מאופיין על-ידי :שם ,מספר טלפון ,וקטגוריה ( בית/נייד/אחר). במחלקה הראשית יש פעולה ראשית הבונה מערך של 50טלפונים סלולאריים .כמו-כן הפעולה קולטת את מספר הפעולה המבוקשת ) ,(1-4מפעילה אותה ,ומעדכנת את תכונות המכשירים בהתאם .הנח כי הפעולות מתבצעות בין שני טלפונים הנמצאים במערך. הפעולות האפשריות הן )1 :חייג-למספר-טלפון )2 ,קבל-שיחת-טלפון )3 ,שלח-הודעה )4 ,קבל-הודעה. א. ב. ג. ד. ה. רשום תרשימי UMLלכל אחד מהטיפוסים הדרושים .חשוב על אפיון יעיל. בנה מחלקה לכל אחד מהטיפוסים. בנה מחלקה ראשית ובה פעולה ראשית המבצעת את המשימות שפורטו בשאלה. הוסף פעולה בוליאנית המקבלת 2טלפונים סלולאריים ובודקת האם הייתה התקשרות כלשהי בין שני הטלפונים .ציין לאיזו מחלקה יש להוסיף פעולה זו. הפעל מהפעולה הראשית את הפעולה שכתבת בסעיף ד עבור כל שני טלפונים הנמצאים במערך הטלפונים ,והצג כפלט עבור כל זוג את מספרי הטלפון ,ואת הערך המוחזר מהפעולה. 40 עיצוב תוכנה – טיפוס מורכב © כל הזכויות שמורות ל'מבט לחלונות' טיפוס מורכב ( – )Composed classטיפוס המוגדר על ידי המשתמש שחלק מן התכונות שלו הן מטיפוס שאינו בסיסי בשפה אשר הוגדר על ידי המשתמש או שהוא כלול בספריות של השפה. העקרונות והיתרונות של תכנות מונחה עצמים באים לידי ביטוי כאשר יש שילוב ושימוש במספרטיפוסים כמו למשל בדוגמה של השילוב בין הטיפוסים :תלמיד ,מורה ,כיתה ,ביה"ס. כללי הפיתוח של טיפוס מורכב הם בדיוק כמו כללי הפיתוח של כל טיפוס: הגדרת תכונות שחלקן מטיפוסים לא בסיסיים שהוגדר על-ידי המשתמש או נמצאים בספריות השפה. פעולה בונה -אם פעולה בונה מקבלת את ערכי התכונות כפרמטרים ,יש ליצור קודם את העצמים המהווים ערכים לתכונות בעצם המורכב שנבנה ,ולשלוח אותם כפרמטרים המתאימים לפעולה הבונה של העצם המורכב. פעולות מאחזרות – לכל תכונה תוגדר פעולה מאחזרת כך גם לתכונות שהטיפוס שלהן אינו בסיסי .במקרים אלה יוחזר עצם שהוא ערך התכונה. פעולות קובעות -לכל תכונה תוגדר פעולה קובעת ,כך גם לתכונות שהטיפוס שלהן הוגדר על- ידי המשתמש .במקרים אלה תקבל הפעולה עצם שהוא הערך החדש של התכונה. מערך של עצמים שימוש במערך של עצמים יכול להיות כמשתנה בפעולה וגם כתכונה של טיפוס חדש .אין הבדל אם מערך העצמים משמש כמשתנה מקומי (בפעולה הראשית או בכל פעולה אחרת) או כתכונה של עצם. למרות עקרון זה יש הבדלים הניכרים במרכיבים הבאים: ( )1בדרך הפנייה אל משתנה או אל תכונה (פנייה ישירה ,או פנייה אל העצם שזו התכונה שלו). ( )2בדרך הגדרת הפעולות – פעולות סטטיות יקבלו את המערך כפרמטר ,פעולות המוגדרות בטיפוס המייצג ישות לא יהיו סטטיות ,וגם לא יקבלו את המערך כפרמטר .פעולות אלו יופעלו על עצם שהמערך הוא אחת התכונות שלו ולכן אין צורך בפרמטר. שלבים בפתרון בעיה בתכנות מונחה עצמים: זיהוי העצמים הנדרשים לפתרון הבעיה. אפיון הטיפוסים של העצמים (טיפוסים המייצגים ישויות). פיתוח כל טיפוס בנפרד (תכונות ,פעולות). פיתוח המחלקה הראשית ובה הפעולה הראשית שבה מופיע האלגוריתם הראשי לפתרון הבעיה .לשרות הפעולה הראשית יכולות להיות מוגדרות גם פעולות סטטיות אחרות במחלקה הראשית. עיצוב תוכנה – טיפוס מורכב © כל הזכויות שמורות ל'מבט לחלונות' 41