
הטקסט המלא של הדקות הראשונות בהרצאה «פרויקט מעשי ב-#C - תוכנת צייר - חלק 31» בקורס הווידאו של PracticU – כתוביות בעברית עם זמן התחלה לכל פסקה. כך תוכלו לקרוא ולחפש את הנושאים לפני שמתחילים ללמוד.
הדבר הבא שאנחנו רוצים לעשות זה לאפשר בעצם עוד תורות למערכת הזו. שתי תורות בסיסיות זה כמובן ה-Free Hand והקו הישר, ה-Line.
עוד תורות שאנחנו רוצים לעשות זה מלבנים מלאים וריקים ועיגולים אליפסות מלאות וריקות. אז בואו נסתכל על הירושה ונראה מה בעצם אפשר לעשות.
ואם נסתכל על שייפ, ונחשוב שמלבן זה סוג של שייפ, אז כן, אז הוא יכול לרשת, מלבן יכול לרשת, מלבן, עיגול, כל אלה, יכולים לרשת משייפ, אבל האמת היא שאולי הם יכולים אפילו לרשת מליין, כי יש להם את פי אחד ואת פי שתיים משותף, זאת אומרת, אפשר תמיד להגדיר, אנחנו נראה את זה בהמשך,
בהגדרה של, צריך לעצור את זה, נעצור אותו, אם נסתכל על דוגמא draw rectangle הפרמטרים שהיא מקבלת זה x, y, width וheight ויש לו עוד שני overloadים, השאלה אם אפשר לראות את זה בואו ניקח רגע את draw rectangle, זה שתיים מתוך שלוש מקבל rectangle, אוקיי בקיצור יש לו, הוא מקבל את x ו-y ו-width ו-height
אבל האמת היא שx ו-y, width ו-height בעצם ניתן להגדיר כמו את P1 ואת P2. אז אפשר להגיד ש... נכון, כי אם אני חושב על מלבן כעל שתי נקודות, ניקח לדוגמה את המלבן שמרכיב את המסכון הקטן הזה שבו אנחנו כותבים את הטקסט, אז נגיד שזו הפינה השמאלית העליונה שלו וזו הפינה הימנית התחתונה שלו.
אז זה בעצם שתי נקודות במרחב שמגדירות מלבן. אז ניתן להגיד שמלבן זה בעצם שתי נקודות, אבל אני מתלבט ואני מעדיף שלא כרגע. אבל בואו נגיד, כן, אבל למעשה ניתן היה תיאורטית לרשת מליין, ולהגיד שמלבן זה איזשהו ליין משופר, אבל זה קצת יכביד, אני לא יודע עד כמה זה יקל כמו שזה יכביד, זה יכביד יותר מאשר יקל.
בקיצור, בואו נעשה שייב נוסף, נקרא לו figure והוא יתאים בעצם לכמה פונקציות גם ל draw rectangle האמת היא שגם ל draw ellipse שזה בדיוק אותו דבר וגם ל fill ellipse שזה אותו דבר וגם ל fill rectangle ששוב זה אותו דבר זאת אומרת כל ארבעת הפונקציות האלה פיל רקטנגל, פיל אליפס, דרו רקטנגל, דרו אליפס
כולם מקבלים עם פחות או יותר אותם פרמטרים, אפילו בדיוק אותם פרמטרים אז אולי נגדיר קלאס אחד שנקרא פיגר, והוא כבר ידע איזה פונקציה להפעיל מה שמיוחד זה שלכולם יהיה x וy וwidth וheight זאת אומרת יהיה להם ארבע שדות שמאפיינים אותם אז נוסיף כאן קלאס חדש, אני אקח את קלאס
line, לא אני לא אקח, אני פשוט אוסיף קלאס חדש נגיד לו אד קלאס ונקרא לו שם כללי פיגר והוא יהיה קלאס אינטרנל והוא יירש כרגע מ-shape מה הצ'וקצ'יק אומר לנו?
אימפלמנט אבסטרקט קלאס שייפ האם אתה רוצה לממש את הקלאס שייפ האבסטרקטי? אני אגיד לו כן תממש מה זה אומר? זה אומר שאתה חייב שיהיה לך את draw ואת update אין לך ברירה בנושא הזה אז הוא כתב לנו את הסטאבים, את התקצירים של דרואו ואפדייט.
השאלה היא מה זה אפדייט? האם אפדייט, האם אפדייט רלוונטית אלינו? מה זה בעצם אפדייט? בואו נגיד לו go to reference, find all references, נמצא רפרנס בפריאנד, לא מעניין אותי, אבל בפון אחד מעניין אותי, וכאן הוא בעצם אומר, אני כבר שכחתי מה זה אפדייט, בואו נראה מה זה,
במרס דאון, כשאני מתחיל לצייר, אז אני אומר לו, פה בעצם הוא כנראה מתחיל, כנראה ש-freehand וגם line צריכים את נקודות הציון ההתחלתיות ובמאוס move freehand אנחנו מוסיפים לו נקודות וגם אומרים לו תצייר כבר באותה הזדמנות את הדלתא ובמאוס up אנחנו אומרים ל-line, ב-freehand אין לנו מה להגיד, במהוס up כי המהוס move האחרון כבר
צייר בליין, במיוס אפ, אנחנו בעצם אומרים לו update, ואומרים לו תצייר את עצמך, יפה, אז האמת היא שכן, זה יכול להיות בעצם רלוונטי גם לפיגר, לפיגורות.
השאלה היא, האם זה לא יותר הגיוני כשכבר אני יוצר את האובייקט, לתת לו את הנקודה הראשונה, למה בעצם לקרוא ל-update בנפרד? למה אנחנו צריכים בעצם את השורה הזו?
למה כבר לא שמנו את זה בקונסטרקטור, את הנקודה הראשונה? הרי אני תמיד יודע את הנקודה הראשונה, אז למה בעצם צריך את הפונקציה Update? אם נסתכל ברפרנסים נראה שיש פה עוד רפרנס מתוך FreeHand, אנחנו קוראים מתוך Update שמציירת, אנחנו קוראים ל-Update שבאמת מעדכנת.
Update, פה אנחנו אמורים לצייר, זה Delta בעצם, וקיבלנו עוד נקודה במרחב שצריך לצייר אליה. אנחנו עושים line to draw line אליה אבל קודם אנחנו מעדכנים במקרה של freehand עוד נקודה שהיא חלק ממערך הנקודות שלנו אז באמת השאלה היא האם אנחנו באמת צריכים את הפונקציה הזו עבור שתי השייפים שלנו line
וfreehand זאת אומרת עכשיו כשאנחנו באים להוסיף עוד קוד בעצם אנחנו מסתכלים ואומרים רגע ואנחנו נעשה משהו דומה לזה וניצור פה new figure ונגיד לו באמת איזה פיגורה הוא יהיה ובעצם לאנור אנור ההצדקה לפונקציה update אז אולי קודם כל ננקה את update כי בעצם אני רואה עכשיו שלא צריך אותה ואפשר את הפרמטרים האלה
תמיד להעביר בקונסטרקטור ועדיף תמיד להעביר כמה שיותר דברים בקונסטרקטור כי בעצם למה לי עוד פונקציה במיוחד, הרי אם יש לי את ה-update, זה אומר שאני יכול לעדכן את הנקודה הזו, ולמה שאני ארצה לפנות בפריד אני מבין, אבל ב-line אני לא רוצה לעדכן בכל זמן נתון. פה במקרה, אחרי שאני יוצא, אני יוצא את זה, אבל אני לא רוצה אחרי זה בכל זמן נתון שתהיה לי את ה-update,
כי ה-update, נלך על ה-update של line, ה-update של line סך הכל היא מסוכנת, או סליחה, ה-update הזאת, סך הכל היא מסוכנת, היא משנה את פי אחד, ובעצם למה לה לי לאפשר את הדבר הזה?
אז בעצם update מיותרת כמו שזה נראה כרגע. נלך לפורום אחד ונוציא את הקריאה ל-update, אבל ניקח את הפרמטרים שאנחנו מעבירים ונוסיף אותם כאן, נעשה copy ונוסיף tick אחרי, ניקח את זה ונשכפל את זה לכאן ואז את זה לא צריך ונלך קודם כל ל-line או נלך קודם כל ל-shape ונדלג על ההגדרה וננטרל או נמחק
את ההגדרה של update שאנחנו רואים שאנחנו לא צריכים אותה ונלך עכשיו לline ואנחנו לא רוצים את ה-update הזו ולמעשה אפשר כבר בקונסטרקטור לשמור את הערכים האלה אם נגדיר כאן נעשה פה paste נגדיר פה את int x ואת int y וניקח את שש השורות האלה ונעביר אותם לכאן ואת הפונקציה update נמחק אנחנו לא צריכים אותה ונלך ל-freehand ונעשה אותו דבר, בעצם
אנחנו את הדבר הזה, שתי שורות האלה, עכשיו פה ניתן לומר שאת שתי השורות האלה אני מבצע גם מתוך ה-update הזו אבל גם אני מבצע את השתי שורות האלה מתוך ה-conspector אז קודם כל נוסיף את השורות האלה, שוב טעות שלי, נוסיף את השורות האלה כאן, int x, int y ונשאיר את הפונקציה update כאן אבל מכיוון שאנחנו מזוהים שגם ה-update משתמשת בה וגם הקונסטרקטור משתמש בה נהפוך אותה ל-private ולא ל-override כי
אנחנו לא יורשים אותה ונקרא, מכאן נמשיך לקרוא ל-update, הפונקציה עצמה, על זה עדיין לא דיברנו עד היום לא דיברנו על פונקציה שיכולה בעצם להיות private אבל הנה גם זה אפשרי, בעצם זאתי, זה מה שנקרא פונקציית שירות פונקציית שירות פרטית, זאת פונקציה שמשרתת רק את הקלאס הנוכחי.
מתי אני מגדיר פונקציה? פונקציה אני מגדיר כאשר יש לי, אלה החוקים שאני גיליתי במהלך השנים, כאשר יש לי למעלה משורה אחת של קוד, במקרה הזה יש לי שתי שורות של קוד, שאני צריך להפעיל בלמעלה ממקום אחד.
אז כאן אני מפעיל את זה במקום אחד, אני אעשה לו copy ונפעיל את זה גם כאן. במקרה שיש לי שתי שורות של קוד שאני מפעיל משתי מקומות, אז אני מגדיר פונקציה Update.
שאם הייתה לי רק שורת קוד אחת כאן, מבחינתי זה לא מוצדק להגדיר פונקציה נפרדת. שורת קוד אחת לא מצדיקה הגדרה של פונקציה נפרדת. זה ככה אני.
יש תכנתים, נקרא לזה אסכולות אחרות, אומרים שכדאי לפעמים יש הצדקה להגדיר פונקציה גם לשורה אחת של קוד אם הקריאה לפונקציה יותר פשוטה מהקריאה, מהכתיבה של הפונקציה, שבעצם של התוכן אם התוכן מאוד מורכב, אפילו שורה אחת עם תוכן
מאוד מסובך תעשה לזה איזושהי מעטפת יותר פשוטה אני לא דוגל בשיטה הזו, אני אומר, כמו שאמרתי, רק שתי שורות שמופעלות בלמעלה משתי מקומות מצדיקות הגדרה של פונקציה מניסיונים אחרי כתיבה של הרבה מאוד שורות קוד החוק הזה נכון והחוק שאומר לכתוב מעטפת פשוטה לקריאה מורכבת לא מוצדק אז הפכנו את
update בעצם ל private ננסה להריץ אז כן לפיגר שעדיין לא התחלנו את הטיפול בו עכשיו יש את update ובעצם אנחנו רואים שאינו צריכים אותו נמחק אותו ונריץ מה הוא עושה?
Line, זה היה דרו-ליין אחרי כל המשחקים דרו-ליין, מריץ שוב ופיגר, או No overload for method shape takes 0 arguments מה בעצם קורה כאן?
אז הקומפיילר שם לב שאנחנו בפיגר ירשנו מ-shape אבל לפיגר לא כתוב שיש קונסטרקטור אז אם לפיגר אין קונסטרקטור, הקומפיילר כותב לה קונסטרקטור דיפולטיבי שנראה ככה הוא נראה ככה, אינטרנל, פיגר, ככה קונסטרקטור דיפוטיבי ריק לא עושה שום דבר אבל הוא כתוב כשאנחנו מנסים להריץ אנחנו מקבלים את השגיאה של no overload for method shape takes 0
ארגומנטים למה? כי עוד דבר שבעצם נכתב לנו פה זה גם הפעלה של קונסטרקטור של הבייס שלא מקבל את הוד שלי רק נקודותיים פה שלא מקבל בלי פיגר שלא מקבל ארגומנטים למרות כמו שאנחנו רואים אין כזה קונסטרקטור באמת הוא צודק no overload for method shape
method shape זה פונקציה וshape זה בעצם הקונסטרקטור no overload for הקונסטרקטור אין overload לשייפ שמקבל אפס ארגומנטים מה זה overload?
overload דומה מאוד למילה override אבל שונה בתכלית Override זה כשאנחנו דורסים את מה שאנחנו יורשים. Overload זה כשאנחנו מעמיסים, ככה הגדירו את המילים, זה התרגומים המקובלים, Overload זה העמסה, Override זה דריסה.
הרעיון הוא שאני יכול להגדיר כמה קונסטרקטורים שאני רוצה. הרבה Overloadים. וההבדל ביניהם הוא איזה פרמטרים הם מקבלים.
במקרה שלנו ל-שייפ יש רק קונסטרקטור אחד שמקבל שני פרמטרים. אין קונסטרקטור ל-שייפ שמקבל אפס פרמטרים. פה הוא צועק ואומר, אין לי קונסטרקטור נוסף, כן? Overload זה, אין לי עוד קונסטרקטור, אין לי העמסת קונסטרקטור ל-שייפ שמקבל אפס ארגומנטים.
יש לי רק אחד, והוא מקבל שני ארגומנטים, שני פרמטרים. וכאן בסיגר, אתה עכשיו אומר לי שבזה שאתה לא כותב כלום, אתה בעצם כותב את זה, וכאן אתה בעצם אומר לי שיש קונסטרקטור ל-shape שמקבל 0 ארגומנטים.
ובכן, אין כזה, והוא צודק. אז אם אנחנו רוצים לכתוב את figure ולא למחוק אותה, אז אנחנו צריכים באמת להעביר את הפרמטרים.
האמת היא שאני כרגע לא צריך את figure, אני יכול פשוט לנטרל אותה בעזרת properties, ובמקום compile אני אומר לו none. זה ה-build action, מה הוא עושה בזמן קומפילציה, האם הוא מקמפל האם הוא מתרגם את זה לא אל תעשה שום דבר עם הקובץ הזה תתעלם מהקיום של הקובץ אני בעצם כרגע עוד לא עוד לא סגור על עצמי מה אני עושה איתו בואו ננסה את זה להעיף
אז זה אחרי שהוצאנו את הפונקציה update נצייר freehand נצייר line הכל נראה מצוין אז נחזור לפיגר נחזיר אותה בואו נראה שימו לב אני יכול גם לקחת את החלון פרופרטיז הזה ולגרור אותו החוטא לגעת בפיגר ולראות את זה כאן בנפרד ולבחור כאן קומפייל אני יכול להחזיר את זה בעזרת גרירה
או בעזרת דאבל קליק נעשה דאבל קליק והחלון פרופרטיז חזר למקומו אנחנו רואים פה את הפרופרטיז של פיגר סי-אף נחזור לסולושן נחזור לסולושן אז עכשיו אנחנו מקמפלים וזה לא יתקמפל כי יש לנו בעיה עם הפיגורה אז בעצם בואו נסתכל על ה-Base Constructor והוא אמור, קודם זה עבד, עכשיו זה מסרב לעבוד, רגע, טוב שהפריע לך לא
עובד, בקיצור הוא אמור לקבל שני פרמטרים color ו-width, אז בואו פשוט נקבל אותם כאן, כי ממילא אנחנו צריכים תמיד לכל שייפ color, color לא נהיה ירקרק, למה הוא לא נהיה ירקרק?
אז כבר למדנו את זה, בואו נעשה עליו, אם אני נוגע בו הוא אמור היה להציג פה את הצ'ופצ'יק, אבל לא תמיד הוא בא לעזרתנו. 2-Caller מוגדר.
אני רוצה לשכפל בעצם את השורה הזאת, כי אני רוצה את ה-U-V שלה, או בעצם את זאת. אז השיכפול הכי מהיר זה קונטרול, C ו-V בבת אחת. זה פשוט משכפל לי.
אני לוחץ על קונטרול וחץ ימינה, הוא קופץ לי לסוף המילה. כן? קונטרול וחץ שמאלה קופץ לי לתחילת מילה. קונטרול וחץ שמאלה קופץ לי. קונטרול שמאלה, קונטרול שמאלה, קונטרול שמאלה.
סיפט וקונטרול ימינה מורח מסמן מאוד מאוד יעיל כמובן קונטרול שיפט זה חצי למטה אה לא עובד דווקא אבל חצי מינה כן אז נחזור לנקודה הזו ונוסיף פה נקודה אז זה סיסטם משהו דרואינג בואו נסתכל בקובץ אחר סיסטם דרואינג סיסטם דרואינג למה הוא לא רואה את זה אני לא יודע היה מקרה כזה שכותב את זה ידנית דרוינג עדיין
זה לא יירקע כנראה נוותר לו ונגדיר פה איזה וויט יש לנו יש לנו פלוט וויט האמת אני לא חושב שלקחת ממש מהנקודה הזו בעצם את כל זה עד לכאן ולקחת את זה לפי כלל האמת לא טוב נעשה פלוט וויט נחשב את זה שתראו הכל פלוט וויט או פלוט אה שיהיה וויט וכאן נעביר לו את סי ואת קונטרול רווח משלים, אני מצפלא,
וננסה לקמפל F6, בילד סקסידד, יפה, למה דרוינג לא בא לעזרתנו כשעשינו לו קונטרול רווח, עכשיו הוא כן רואה אותו, אז, לא יודע, אולי כי זה בטא, באגים, בכל מערכת יש באגים.
טוב, דרו כרגע עדיין לא קיימת, המערכת מתקמפלת, אז זהו, מה אנחנו בעצם רוצים שפיגירי יהיה? נחזור לטופס הראשי שלנו, ובעצם במהוס דאון אנחנו מחליטים ליצור משהו.
אז עד היום היה לנו רדיו באדן פריאנד ורדיו באדן ליין, בואו לגוי בעזרת F7, אני הולך לגוי של הטופס של הקוד הנוכחי, F7 גם מחזיר אותי לקוד, שהוא F7, וכמו שיש לי פה שני כפתורים אני רוצה בעצם להוסיף עוד, אז ניקח את זה ונשכפל אותו, קופי, פייסט ועוד
אחד. בעצם אני רוצה עכשיו מלבן ריק, מלבן מלא, אליפסה ריקה ואליפסה מלאה. אז נתמצת את הקיצורים, את האותיות וזה יהיה פילד רקטנגל, נתחיל מנון פילד רקטנגל ובטול טיפ נכתוב נון פילד רקטנגלה ככה וזה גם יהיה השם של ה-radio button נוציא רק את זה וזה יהיה פילד רקטנגל נוציא את הנון נהפוך את ה-f לגדולה וניקח
את זה נעשה enter ו-end מעביר אותי לסוף חץ למעלה לטקסט טאב מעביר אותי לכאן פייסט זהו זה אמור להיות רק פילד רקטנגל אני יורד עם חץ למטה טאב פייסט ופילד רקטנגל אנטר אני יכול לעשות אסקייפ שמחזיר אותי לטופס מפה tab מעביר אותי, מעביר אותי לכאן ו-f4 מעביר אותי ל-properties אז זה ה-non-field rectangle, זה ה-non-field ellipse, tab זה non-field ellipse אני בסוף שיפט home מסמן
לי הכל ctrl c עושה לי קופי enter חץ למעלה tab זה אמור להיות non-field ellipse enter home מעביר אותי למעלה חץ למטה פעמיים tab end backspace שימו לב אני עובד בלי עכבר זה הרבה יותר מהר בסוף היום ctrl v ctrl חץ שמאלה backspace enter escape tab f4 tab end חץ אחורה ctrl v זה זה אמור להיות פילד שיפט אפטר אנד פילד אליפס קונטרול שיפט
אס עושה סייב אול טוב אז עכשיו צריך בעצם ליצור את הדברים האלה אז נחזור שוב לקוד של פיג לא של פיג סליחה של פורם אחד וכאן בעצם אנחנו נשכפל את השורה הזו אז אם רדיו בטן, נתחיל לפי הסדר מ-non-field-rectangle, קונטרול רווח, חץ למטה, אנטר אם הוא צ'ק, אז אני יוצר פיגר חדש, אנטר פיגר, אז זהו, אני רוצה שהיא תדע מה היא
אז אני צריך בעצם חוץ מה-color וה-Weight, ואולי באמת ה-XY אני רוצה גם להגיד לה איזה מין סיגוריה היא תהיה אז יש לנו בעצם שני סיגורות ליפס ורקטאנגל וכל אחת יכולה להיות פילד או לא פילד אז בואו נגיד נלך רגע לתוך פיגר F12 ונגדיר פה אינטרנל בול איז פילד האם זה מלא האם הצורה הזו מלאה
סליחה, נעשה את זה בעצם פרייבט וריד און מי, ודבר ראשון נקבל פה את בול is field. פה נוסיף אנדרסקור, ופה נקבל את הערך is field שווה ל-is field, זה דבר ראשון.
והדבר השני, בעצם הפיגורה עצמה, מה הצורה שלה? כרגע יש לנו רק אליפ ורקטנגל, אני לא הייתי רוצה להגיד בול is אליפ, אם זה לא אליפס אז להניח שזה רקטאנגל זה קצת לא קריא הייתי רוצה להשתמש באינם אבל אני רוצה שהאינם הזה יהיה מוכר גם מבחוץ אז נגיד, אז זהו, אבל אני רוצה שהוא יהיה של פיגר
זאת אומרת אני לא רוצה שבאינם הזה ישתמשו מחוץ לפיגר כי אין לזה הדבקה וכבר אמרנו מה שלא מצדיק את עצמו אסור שיהיה בעצם הדבר שאני רוצה לעשות פה זה להגיד אינטרנל אינם תכף נמשיך את זה, אבל שימו לב שאני כותב את זה בתוך הקלאס ולא מחוץ לקלאס אם הייתי כותב את זה מחוץ לקלאס בתוך הניימספייס
אז אין לזה משמעות אם זה בקובץ הזה או בכל קובץ אחר מחוץ לקלאס בתוך הניימספייס זה היה כאילו נחשב אותו מקום אני בכוונה כותב את זה בתוך הקלאס פיגר כדי שזה יהיה ברור שזה שייך לפיגר ונראה בהמשך עד כמה שזה ברור בינתיים נגדיר פה רק אולי טייפס שוגים של פיגורות לדוגמה רקטנגל ואיליפס אולי בהמשך יהיו לנו עוד ואני משכפל את השורה הזו ונגדיר
private read-only מסוג טייפס ואני קורא לזה underscore type הטייפס שלנו שהוא מסוג טייפס משכפל את שני אלה שם אותם כאן אולי אני פה מוריד את האנדרסקור ופה נגיד אנדרסקור טייפ, הסוג שווה ל... למה? לטייפ שקיבלנו, לזה.