יצירת מופע של מחלקה יורשת במחלקה מורישה מתוך עצמה
-
שלום לכולם
יש לי 3 מחלקות, אחד אב, והשניים האחרות יורשות, כעת אני צריך מופע אחד של אב, ו 2 מופעים שווים של ילדים, שיורשים מתוך אותו מופע עצמו של האב.
הבעיה היא, שאני צריך להצהיר על הילדים כל עוד אני בתוך האב, ויש לאב הזה קונסטרקטור שמקבל ערך פרימיטיבי. מה שקורה כשיוצרים מופע של מחלקה יורשת, בדרך כלל הוא יוצר אוטומטית מופע חדש של המחלקה המורישה, ואי אפשר לייחס מופע קיים של המוריש ליורש. מה שתוקע כאן את העסק הוא שאני צריך לקרוא ל 2 מחלקות יורשות, ואני צריך ששתיהן תירשנה מאותו מופע של האב, ואם אני אצור 2 מחלקות יורשות בנפרד, יווצרו לי 2 אבות, הואיל והאב תמיד מקבל ערך פרימיטיבי ולא הפניה למחלקה. מה שיוצר 2 בעיות, א) רקורסיה אינסופית ב)שזה פשוט לא אותו מופע. אם נפתור אחת מהן השניה כבר תיעלם לבד.....
זאת הדוגמא:namespace ConsoleApplication1 { class Program { static void Main(string[] args) { new A(1); } } class A { int Father; B b; Random rnd = new Random(); public A(int father) { this.Father = father; b = new B(Father); System.Diagnostics.Debug.Print(rnd.Next(1,100).ToString()); } } class B : A { public B(int father) : base(father) { } } class C : A { public C(int father) : base(father) { } } }
הפתרון הנראה לעין הוא לוותר על רעיון ההורשה, אלא ליצור מצביעים בתוך כל מחלקה שמפנים למופע הרצוי. הבעיה היא שאני לא מוגן מפני כפילויות, ואם תמצי לומר סינגלטון, זה יגביל אותי למופע אחד בכל התוכנה, ואני יש לי הרבה מופעים של הורים (וגם במקביל אם עובדים עם טרד).
פורסם במקור בפורום CODE613 ב13/05/2014 14:18 (+03:00)
-
לא הבנתי לגמרי מה אתה רוצה.
א. כל המושג ירושה הוא במחלקות, מופע לא יורש ולא יורשים ממנו.
ב. כשיוצרים מופע מתת מחלקה הקונסטרקטור שלה נקרא תחילה. אח"כ של האב.
ג. בתוך מחלקת בסיס ניתן לבדוק אם המופע הנוכחי (this) הינו ממחלקה נגזרת.מאוד יעזור שתסביר מה אתה רוצה בסופו של דבר. תוכל לתת לנו סיטאציה חיה (מפעל עם עובדים, או בית חרושת לנעליים) שמולידה צורך דומה למה שאתה רוצה.
פורסם במקור בפורום CODE613 ב13/05/2014 14:30 (+03:00)
-
תחשוב שיש לך את כדור הארץ, בתוכו יש מדינות, בתוך המדינות ערים, בתוך הערים שכונות, בתוך השכונות רחובות, בתוך הרחובות בתים.
לפי ההיגיון תוכנה לניהול כוכבי לכת צריכה להוריש את מאפייני הכוכב למדינה, ומדינה לעיר וכך בסדר היררכי עד למופע של ה"בית".
כעת תאר לעצמך שאתה יוצר מופע של 3 בתים, אז יש לך 3 מופעים של מחלקת כוכב. בשביל מה?? אני מבין שצריך להיות מופע אחד ויחיד של כוכב, אשר כל מאפייניו ופונקציותיו וכו' מחלחלים בשווה לכל העץ. וכאשר משנים ערך של מאפיין כוכב, גם אם עושים את זה מבית אחד, כל הכוכב משתנה, וכל הבתים מקבלים עדכון שעכשיו יום או לילה.
מאוד פשוט.פורסם במקור בפורום CODE613 ב13/05/2014 14:40 (+03:00)
-
ההיררכיה שציירת היא היררכיית מופעים, לא מחלקות. ייתכן שיש בחלה גם היררכיית מחלקות, אבל בא נניח שאין.
במקרה כזה אתה צריך לעבוד כמו שהעלית את האפשרות עם מאפיינים המצביעים על האב/ילדים/אחים.הנה דוגמה בסיסית:
namespace ConsoleApplication1 { class Program { static void Main(string[] args) { var israel = new State(); var Jerusalem = new City (israel); var Yafo = new Street(Jerusalem); var MyHome = new Home(Yafo); Console.WriteLine("My Home is: {0}", MyHome); Console.WriteLine("My Street is: {0}", MyHome.Street ); Console.WriteLine("My City is: {0}", MyHome.Street.City ); Console.WriteLine("My State is: {0}", MyHome.Street.City.State); } } class State { } class City { public State State { get; set; } public City(State state) { State = state; } } class Street { public City City { get; set; } public Street(City city) { City = city; } } class Home { public Street Street { get; set; } public Home(Street street) { Street = street; } } }
בשביל לשלוט על אוספי המדינות וכו' כמו שאמרת למנוע יצירת כפולים וכדומה הרעיון של סינגלטון דומה למה שצריך לעשות. צריך לעשות אוסף פנימי של כל המדינות, ויצירה של מדינה חדשה היא רק ע"י פונקציה סטטית שחברה במחלקת המדינות. הנה הצעת הגשה:
namespace ConsoleApplication1 { class Program { static void Main(string[] args) { var state = State.GetState("israel"); ... } } class State { private State() {} //בנאי פרטי מונע יצירת חדשים בדומה לסינגלטון //אוסף פנימי מסוג המופע עצמו - אוסף מדינות static Dictionary<string, State> StateCollection = new Dictionary<string, State>(); //פונקציה ציבורית לקבלת מדינה (קיימת או לא) public static State GetState(string name) { State result; if(StateCollection.TryGetValue(name, out result) == false) { result = new State(); //מתוקף היות הפונקציה בתוך המחלקה היא רשאית לבנות חדש StateCollection.Add(name, result); } return result; } } }
כמובן שבמקרה אמיתי נכלול במדינה מאפיין עבור שמה ("Israel") ולא נסתמך על הKEY שמחזיק אותה (או שם המשתנה כמו בדוגמאות שלי...).
היררכיית ירושה לא משקפת כלל את הקשר בין המופעים, אלא את הדימיון/נגזרות בין הג'ובים של כל חלק (מחלקה) בתוכנה. מאוד ייתכן (ממש לא מוכרח) שתהיה כאן איזושהי היררכיית ירושה, אבל ממש בלי קשר להיררכיית המופעים. כלומר ייתכן שדוקא מדינה תירש מרחוב - הכל לפי המאפיינים והמתודות האופייניים למחלקות אלו. זה בעצם היררכיית זמן עיצוב. נניח בדוגמה האחרונה גם לרחוב יפו וגם לבית שם יש אותה מדינה בזמן ריצה, אבל אין להם משותף כלל מבחינת זמן העיצוב. הדמיון שכן אפשר למצוא ביניהם, זה למשל שלשתיהם יש מאפיין של מיקום במפה.
אם רוצים שלכל ההיררכיה יהיו מאפיינים ישירים לסבותיהם (אולי זה מה שהתכוונת, סליחה שלקח לי זמן להבין), אז יש כאן מקום להיררכיית זמן עיצוב: גם למחלקת רחוב וגם למחלקת בית יש מאפיין בשם מדינה. אפשר לחסוך את החזרה על הלוגיקה של הצהרת המאפיין ואתחולו גם ברחוב וגם בבית. משהו כזה:
class City { public State State { get; set; } public City(State state) { State = state; } } class Street : City { public City City { get; set; } public Street(City city) : base (city.State ) { City = city; } } class Home : Street { public Street Street { get; set; } public Home(Street street) : base (street.City) { Street = street; } }
ואז כשיש לנו ביד בית, ואנו רוצים לדעת את מדינתו, במקום לכתוב כמו למעלה ככה:
Console.WriteLine("My State is: {0}", MyHome.Street.City.State);
נוכל לכתוב ישירות:
Console.WriteLine("My State is: {0}", MyHome.State);
על אף שלא כתבנו מאפיין State במחלקת Home, וזה אודות לירושה.
סליחה על הדרשה, ובהצלחה!
פורסם במקור בפורום CODE613 ב13/05/2014 15:26 (+03:00)
-
כעת אני חושב, שלו נרצה לשתף את הפונקציונליות של ההגנה על יצירת חדשים, היה עלינו לגזור את מדינה עיר ורחוב ממחלקת בסיס עם ה"פטנט" הזה (רשימה פנימית סטטית ומחלקה שמחזירה איבר קיים או יוצרת חדש).
אך הבעיה שהן הרשימה והן המתודה חייבים להיות סטטיים, וזה אומר שלא זו בלבד שאין ירושה אלא גם מדובר באותה הרשימה (למדינות והערים והרחובות) למעשה אני לא מצאתי בראש דרך לירושה כזו.פורסם במקור בפורום CODE613 ב13/05/2014 16:18 (+03:00)