ניתוח מערכות מידע ב נעים להכיר... תכנות ב C# 1 ניתוח מערכות מידע ב' מרצים מכון לב -ד"ר אבי רוזנפלד מכון טל – ד"ר אריאלה ריכרדסון שעות קבלה: בתאום מראש בדוא"ל אתר הקורס – http://www.jct.ac.il/~rosenfa/nituach2 עדכונים מצגות דוגמאות וחומר לחזרה סילבוס נושאים שילמדו בקורס הכרות עם C# תיכנון מונחה עצמים מתקדם Polymorphism, composition, association תרשימי UMLמתאימים בניית ממשק למשתמש הכרות ADO שילוב בין בסיסי נתונים ו#C פרויקט מסכם ספרים Requirements Analysis and System Design, 3rd ed. Leszek A. Maciaszek Object-Oriented Systems Analysis and Design Using UML, 3rd ed. , Simon Bennett, Steve Mcrobb, Ray Farmer #C כשפת אם. – Object Oriented Design .net framework. יצחק גרבר. Visual C# 2010, How to Program (4th Edition), Deitel and Deitel. Pro Asp.Net 4 in C# 2010, 4th ed. Matthew MacDonald, Adam Freeman, and Mario Szpuszta. הכרות עם C# פקודות כלליות 5 טיפול בקלט ופלט- דוגמא using System; class IOProgram { static void Main(string[] args) { Console.WriteLine("Please Type Something:"); String x; x = Console.ReadLine(); Console.WriteLine("You typed {0}" , x ); Console. ReadKey(); } } 6 קלט של מספרים using System; class numberProgram { static void Main(string[] args) { String x; int y; Console.WriteLine("Enter a number:"); x = Console.ReadLine(); y = int.Parse(x); Console.WriteLine("You typed {0}" ,x); Console.WriteLine("Adding 2 makes: {0} or {1}", x+2, y+2 ); Console. ReadKey(); } } 7 if - דוגמא using System; class ifProgram { static void Main(string[] args) { string x; x = Console.ReadLine(); if (x == "a" || x == "A") Console.WriteLine("A is for apple"); else if (x == "b" || x == "B") Console.WriteLine("B is for Boy"); else Console.WriteLine("Not defined"); Console.ReadKey(); } } 8 for - דוגמא using System; class ifProgram { static void Main(string[] args) { for (int i = 0; i < 100; i++) Console.WriteLine("The square root of {0} is {1} ", i, Math.Sqrt(i) ); Console.ReadKey(); } } 9 while - דוגמא using System; class FirstProgram { static void Main(string[] args) { int NUM_GAMES = 12; int won; double ratio; Console.WriteLine("Enter num of games won (0 to {0})", NUM_GAMES); string tmp = Console.ReadLine(); won = int.Parse(tmp); while (won < 0 || won > NUM_GAMES) { Console.WriteLine ("Invalid input. Please reenter: "); tmp = Console.ReadLine(); won = int.Parse(tmp); } ratio = (double)won / NUM_GAMES; Console.WriteLine ("Winning percentage is: {0}", ratio); } } 10 int grade, category; Console.WriteLine("Enter a numeric grade (0 to 100): "); string tmp = Console.ReadLine(); grade = int.Parse(tmp); category = grade / 10; switch (category) { case 10: Console.WriteLine("Perfect score. Well done."); break; case 9: Console.WriteLine("Well above average. Excellent."); break; case 8: Console.WriteLine("Above average. Nice job."); break; case 7: Console.WriteLine("Average."); break; default: Console.WriteLine("Study some more."); break; } 11 C# לVB הבדלים בין אופרטורים של Purpose VB.NET C# Integer division \ / Modulus (division returning only the remainder) Mod % Exponentiation ^ n/a Integer division Assignment =\ =/ Concatenate =&NEW =+ Modulus n/a =% Bitwise-AND n/a =& Bitwise-exclusive-OR n/a =^ Bitwise-inclusive-OR n/a =| Equal = == Not equal >< =! Compare two object reference variables Is == Compare object reference type TypeOf x Is Class1 x is Class 1 Concatenate strings & + Shortcircuited Boolean AND AndAlso && Shortcircuited Boolean OR OrElse || Scope resolution . .and base 12 C# לVB הבדלים בין אופרטורים של ...המשך Purpose VB.NET C# Array element )( ] [ Type cast Cint ,CDbl ,... ,CType )type) Postfix increment n/a ++ Postfix decrement n/a -- Indirection n/a ( *unsafe mode only) Address of AddressOf ( &unsafe mode only; also see fixed) Logical-NOT Not ! One's complement Not ~ Prefix increment n/a ++ Prefix decrement n/a -- Size of type n/a sizeof Bitwise-AND And & Bitwise-exclusive-OR Xor ^ Bitwise-inclusive-OR Or | Logical-AND And && Logical-OR Or || Conditional If Function)( :? Pointer to member n/a ) .Unsafe mode only) 13 מחלקות 14 עקרונות בתכנון מונחה עצמים תכנון מונחה עצמים תומך בעקרונות הבאים הכמסה – encapsulation נלמד עכשיו ירושה – inheritance נלמד בהמשך פולימורפיזם polymorphism - 15 חשבון הבנק – מחלקה ואוביקט שם מחלקה תכונות פעולות 16 מחלקה (הרעיון/תבנית) שם מחלקה תכונות +ערכים אוביקטים (המימוש) שם אוביקט נראה תחילה איך מייצרים מחלקה 17 מהי הכמסה ()encapsulation אפשר להסתכל על מחלקה בשני אופנים פנימי 18 פנימי – הפרטים של המחלקה ,התכונות והפעולות שלה חיצוני – השירותים שהמחלקה מספקת חיצוני מהי הכמסה ()encapsulation אפשר להסתכל על מחלקה בשני אופנים פנימי 19 פנימי – הפרטים של המחלקה ,התכונות והפעולות שלה חיצוני – השירותים שהמחלקה מספקת חיצוני - publicמאפשר גישה גם מחוץ למחלקה תכונות בדרך כלל תכונות לא יוגדרו public מתודות 20 בדרך כלל יוגדרו publicשכן הן מיועדות לשימוש מחוץ למחלקה מאפשר גישה למתודות מחוץ למחלקה מאפשר גישה מכל מתודות המחלקה get, set כיוון שאין גישה לתכונות המחלקה באופן ישיר ,מקובל להגדיר מתודות גישה לתכונות מתודות אלו נקראות בשמות - getXמחזירה את ערך התכונה ( Xנקרא גם )accessor - setXקובע את ערך התכונה ( Xנקרא גם )mutator מתודות getו set -מאפשרות גישה מבוקרת לתכונות המחלקה 21 ניתן להגביל טווח ערכים ניתן לבדוק שהערכים תקינים כאשר אין צורך לא נגדיר לתכונות מתודות getו set VOID דוגמא של פונקציה של namespace ConsoleApplication1 { class Program { public static void XYZ() { Console.WriteLine("There"); } public static void Do(int x) { Console.WriteLine(x+2); } static void Main(string[] args) { XYZ(); Do(4); int y = 3; Do(y); Console.WriteLine("Hi"); } } } 22 דוגמא של פונקציה שמחזירה ערך namespace ConsoleApplication1 { class Program { public static int XYZ(int x) { return x + 2; } static void Main(string[] args) { XYZ(4); int y = 3; XYZ(y); Console.WriteLine("Hi"); } } } 23 דוגמא של מערך namespace ConsoleApplication1 { class Program { static void Main(string[] args) { int[] numbers = new int[10]; // numbers is a 10-element array numbers[0] = 1; numbers[2] = -3; for (int i = 0; i < 10; i++) Console.WriteLine("pos " + i + " is " + numbers[i]); } } } 24 BankAccount למימוש מחלקהC# קוד using System; public class BankAccount { private String name; private float balance; תכונות public BankAccount(String name) { //constructor body } בנאי )constructor( public float getBalance( ) { //method body } public void deposit(float sum) { //method body } )פעולה (מתודה public void draw(float sum) { //method body } } 25 1 המימוש המלא – חלק using System; public class BankAccount { //attributes private String _name; private float _balance; //constructor public BankAccount(String name) { _name = name; _balance = 0; } המשך בשקף הבא 26 2 המימוש המלא – חלק //methods public float getBalance( ) { return _balance; } public void deposit(float sum) { _balance += sum; } public void draw(float sum) { _balance -= sum; } } 27 מתודות -דגשים דגשים 28 כותרת המתודה הצהרת מתודה מתחילה בכותרת סוג גישה )public int calc (int num1, int num2 רשימת פרמטרים רשימת הפרמטרים מגדירה עבור כל פרמטר את הטיפוס שלו ואת שמו 29 שם המתודה טיפוס הערך המוחזר גוף המתודה לאחר הכותרת מגיע גוף המתודה )public int calc (int num1, int num2 { ;int sum = num1 + num2 ;return sum sumהוא משתנה לוקלי הוא מיוצר בכל פעם שהמתודה נקראת ומושמד כאשר מסיימת להתבצע 30 } הטיפוס שמחזירים צריך להיות זהה לטיפוס הערך המוחזר פקודת return טיפוס הערך המוחזר של מתודה קובע את הטיפוס של הערך שיוחזר למקום ממנו נקראה המתודה )public int calc (int num1, int num2 { ;int X // do something ;return X } למתודה שלא מחזירה ערך יש טיפוס ערך מוחזר void )public void calc (int num1, int num2 { // do something } 31 פקודת return (המשך) פקודת ה return-קובעת את הערך המוחזר )public int calc (int num1, int num2 { ;int X // do something ;return X הערך שיש ב Xיוחזר } ניתן גם להחזיר ערך של ביטוי 32 הערך המוחזר ע"י הביטוי צריך להתאים לטיפוס הערך המוחזר )public bool calc (int num1, int num2 { ;return num1<num2 } בנאי contructor - בנאי ( )constructorהיא מתודה מיוחדת לכל מחלקה יש להגדיר בנאי שם הבנאי זהה לשם המחלקה הבנאי אינו מחזיר ערך הבנאי נקרא באופן אוטומטי כאשר אוביקט נוצר בדרך כלל נבצע פעולות של איתחול בבנאי יתכנו מספר בנאים למחלקה אחת 33 לכל אחד מהבנאים יש לקבוע רשימת פרמטרים שונה בנאים public class BankAccount { private String _name; private float _balance; //constructor without parameters public BankAccount() { _name = null; _balance = 0; } בנאי יכול להופיע ללא פרמטרים או עם פרמטרים אם, אפשר להגדיר מספר בנאים יש לכל אחד פרמטרים שונים מספר שונה של פרמטירם או טיפוסים שונים של פרמטרים //constructor with parameters public BankAccount(String name) { _name = name; _balance = 0; } } 34 בנאים -ערך מוחזר לבנאים אין ערך מוחזר!!! אפילו לא void טעות נפוצה – לתת טיפוס לבנאי גורם לבנאי להיות מתודה רגילה במידה ולא הוגדר בנאי למחלקה: 35 יוגדר באופן אוטומטי בנאי ריק לבנאי הריק אין פרמטרים הבנאי הריק לא מבצע שום פעולה שימוש במחלקות ואוביקטים דגשים 36 יצרנו את המחלקה, עכשיו נרצה לייצר אוביקטים אוביקטים (המימוש) 37 BankAccount ליצירת אוביקטים שלC# קוד using System; public class test { static void Main(String[] args) { BankAccount Account1 = new BankAccount("Tamar"); BankAccount Account2 = new BankAccount("Moshe"); Account1.deposit(20000); Account2.deposit(100); Account2.draw(600); יצירת אוביקטים שימוש בפעולות } } 38 יצירת אוביקטים משתנה מכיל טיפוס בסיסי (… )int, floatאו הצבעה לאוביקט ניתן להצהיר על משתנה מטיפוס מחלקה כלשהי לא נוצר אוביקט בהצהרה הנ"ל!! המשתנה מכיל כתובת בזכרון עבור האוביקט ;Circle circ1 יש לייצר את האוביקט במפורש ע"י שימוש ב newהמבצע קריאה לבנאי ;)( circ1 = new Circle ניתן לשלב את שתי הפעולות ביחד: 39 ;diameter = 30 ;xPosition = 20 ;yPosition = 60 ;"color = "blue ;isVisible = false ;)( Circle circ1 = new Circle circ1 הפעלת מתודות ברגע שיצרנו אוביקט אפשר להשתמש באופרטור ' '.כדי להפעיל מתודות שלו. ;int size=0 ;Circle circ1 ;)(circ1 = new Circle ;)circ1.moveHorizontal(10 ;)(size = circ1.getSize מתודה יכולה להחזיר ערך (כמו )()getSize ניתן להשתמש בערך לביצוע השמה או בתוך ביטוי אפשר לחשוב על קריאה למתודה כ"הפעלת שירות של המחלקה" 40 העמסה overloading - ראינו כבר שאפשר לייצר כמה בנאים ניתן לתת הגדרות שונות גם למתודות רגילות העמסה ( – )overloadingיש מספר מתודות עם אותו שם על החותמת ( )signatureשל המתודה להיות יחודית ,כלומר: מספר הפרמטרים ,הטיפוס שלהם והסדר שלהם הטיפוס המוחזר אינו חלק מהחותמת 41 כלומר אסור ששני מתודות יבדלו רק ע"י הטיפוס המוחזר העמסה – רשימת הפרמטרים הקומפיילר קובע לאיזה מתודה לקרוא ע"י ניתוח הפרמטרים static float tryMe(int x) { return x + 10; } ?מי יופעל result = tryMe(25, 5) static float tryMe(int x, int y) { return x*y; } 42 null null הוא ערך מיוחד עבור אוביקטים משמעות nullהוא "שום דבר" טיפוסים פרימיטיבים (… )int, float,לא יכולים לקבל null מקביל ל Nothingב VB ניתן לתת לאובייקט ערך nullבצורה הבאה: ;String s = null אפשר גם לבדוק אם אובייקט מסויים הוא :null if (s == null) // Do something האובייקטים שהוכרזו אך לא אותחלו -מכילים ערך .null ניסיון לבצע פעולה על אובייקט שהוא nullיגרור קריסה של התוכנית 43 Enumerated Types משתמשים ב enumכדי להגדיר טיפוס המקבל ערכים מוגדרים מראש שקול ל Enumשל VB למשל נגדיר טיפוס שנקרא Season ;}enum Season {winter, spring, summer, fall ניתן להגדיר כמה ערכים שנרצה לאחר ההגדרה ניתן להגדיר משתנים מהטיפוס החדש ;Season time ולאתחל ערכים ;time = Season.fall 44 בנאי העתקה 45 Point המחלקה . של נקודה במרחבPoint נגדיר מחלקה בשם Y ורכיבX רכיב,למחלקה שני מאפיינים public class Point { private double _x,_y; public Point(double x, double y) { _x = x; _y = y;} public double getX() { return _x; } public double getY() { return _y; } public void setX(double x) { _x = x; } public void setY(double y) { _y = y; } } 46 toString הוספת מתודה public class Point { private double _x,_y; public Point(double x, double y) { _x = x; _y = y;} public double getX() { return _x; } public double getY() { return _y; } public void setX(double x) { _x = x; } public void setY(double y) { _y = y; } public String toString() {//return the relevant string return _x + "," + _y; } } 47 השמה של אוביקטים עבור אוביקטים השמה מעתיקה את הכתובת 1 2 p1 Before: ;Point p2 = p1 1 2 p1 p2 Then: ;)p2.setX(5 5 2 48 p1 p2 After: :מה שרוצים לייצר אוביקט חדש שהתוכן שלו זהה לישן Before: p1 1 2 Point p2 = new Point(p1) Then: p1 1 2 p2 1 2 p1 1 2 p2 5 2 p2.setX(5); After: 49 הפתרון :בנאי העתקה בנאי העתקה copy constructor משכפל אוביקט מייצר אוביקט חדש מאתחל את האוביקט החדש באופן זהה לישן 1 2 50 p1 p2 )copy constructor( הוספת בנאי העתקה public class Point { private double _x,_y; public Point(double x, double y) { _x = x; _y = y;} //copy constructor public Point(Point otherPoint) { _x = otherPoint._x; _y = otherPoint._y; } public double getX() { return _x; } public double getY() { return _y; } public void setX(double x) { _x = x; } public void setY(double y) { _y = y; } public String toString() {//return the relevant string return _x + "," + _y; } } 51 העברת אוביקטים 52 העברת אוביקט כפרמטר Point נראה דוגמא במחלקה- אפשר להעביר אוביקט כפרמטר נממש מתודה שמחשבת מרחק בין הנקודה של האוביקט לנקודה אחרת : נקודות מוגדר2 מרחק בין dist ( x2 x1 ) ( y2 y1 ) 2 2 public double distance(Point otherPoint) { double diffX = Math.Pow(_x-otherPoint._x,2); double diffY = Math.Pow(_y-otherPoint._y,2); return Math.Sqrt(diffX+diffY); } 53 החזרת אוביקט ממתודה ב Point נממש מתודה שמחזירה את הנקודה באמצע הדרך מהמרכז ( )0,0לנקודה של האוביקט עבור הנקודה ( )10,4תחזיר ()5,2 עבור הנקודה ( )4,7תחזיר ()2,3.5 )(public Point halfPoint { ;double halfX = _x/2 ;double halfY = _y/2 ;)Point halfPoint = new Point(halfX, halfY ;return halfPoint 54 } :עוד דרך להחזרת אוביקט return בתוך פקודת הnew אפשר לבצע את ה public Point halfPoint() { return new Point(_x/2,_y/2); } 55 halfPoint דוגמא לשימוש במתודה Point p1 = new Point(10,4); Point p2 = new Point(4,7); Point middlePoint = p1.halfPoint(); Console.WriteLine(p2.halfPoint()); :פלט 2.0,3.5 56 אוביקט כתכונה Aggregation 57 אוביקט כתכונה נרצה להגדיר למחלקה תכונות שהן מחלקה אחרת שיצרנו. מאפשר שימוש חוזר של קוד ובנייה של מחלקות מורכבות נניח נרצה ליצור מחלקה המתארת מעגל הגדרנו מחלקה עבור נקודה 58 Point נגדיר מחלקה עבור מעגל תכונה :1המרכז (מסוג )Point תכונה :2רדיוס radius Point public class Circle { private double _radius; private Point _center; //constructor 1 public Circle(double r, double x, double y) { _radius = r; _center = new Point(x, y); } //constructor 2 public Circle(double r, Point p) { _radius = r; _center = new Point(p); } הגדרת המעגל !שימו לב בכל הבנאים על מנת לאתחל את המרכז new יש לבצע } 59 public class TestCircle { static void Main(String[] args) { הגדרת המעגל //making a circle using radius and x,y coordiantes Circle circ1 = new Circle(10,2,4); //making a circle using a radius, and a point Point pt = new Point(5,6); Circle circ2 = new Circle(20, pt); what if we want to print the circle information? } } 60 public class Circle { private double _radius; private Point _center; הגדרת המעגל //constructor 1 public Circle(double r, double x, double y) { _radius = r; _center = new Point(x, y); } //constructor 2 public Circle(double r, Point p) { _radius = r; _center = new Point(p); } כאן נקראת מתודת toString של Point //toString public String toString() { return ("radius is " + _radius + ",\t" + "center is " + _center); } } 61 public class TestCircle { static void Main(String[] args) { הגדרת המעגל //making a circle using radius and x,y coordiantes Circle circ1 = new Circle(10,2,4); //making a circle using a radius, and a point Point pt = new Point(5,6); Circle circ2 = new Circle(20, pt); //Now we can print Console.WriteLine("circ1: " + circ1.ToString()); Console.WriteLine("circ2: " + circ2.ToString()); } } 62 public class Circle { private double _radius; private Point _center; הגדרת המעגל //constructor 1 public Circle(double r, double x, double y) { _radius = r; _center = new Point(x, y); } //constructor 2 public Circle(double r, Point p) { _radius = r; _center = new Point(p); } //toString public String ToString() { return ("radius is " + _radius + ",\t" + "center is " + _center.ToString()); } public void setRadius(double r) { _radius = r; } public double getRadius() { return _radius; set & get ) double עבור רדיוס (טיפוס } } 63 ' אפשרות א- setCenter y וx המתודה תקבל את הקואורדינטות public void setCenter(double x, double y) { _center.setX(x); _center.setY(y); } public void setCenter(double x, double y) { _center._x=x; _center._y=y; } לא ניתן לגשת לתכונות מסוגcenter פרטיות של !!! Point 64 ' אפשרות ב- setCenter משתמש בבנאי העתקה Point של )המתודה תקבל מרכז (נקודה )(העברת אוביקט כפרמטר public void setCenter(Point p) { _center = new Point(p); } public void setCenter(Point p) { _center =p; } aliasing או public void setCenter(Point p) { _center.setX(p.getX()); _center.setY(p.getY()); } public void setCenter(Point p) { _center._x = p._x; _center._y = p._y; } private 65 - getCenterהנכון הדרך הנכונה להחזרת המרכז: במקרה זה יוחזר העתק של התכונה )(public Point getCenter { ;)return new Point(_center } עקרון ההכמסה ( )encapsulationנשמר. 66 שימוש בבנאי העתקה אם היינו מחזירים בלי newהיה אפשר לשנות מחוץ למחלקה public class TestCircle { static void Main(String[] args) { דוגמאות לשימוש :set, get הגדרת המעגל Circle circ1 = new Circle(10, 2, 4); //set and get as usual circ1.setRadius(100); double rad2 = circ1.getRadius(); //set using coordinates circ1.setCenter(7, 8); //set using a Point Point p3 = new Point(9, 9); circ1.setCenter(p3); //get returning a Point Point center2 = circ1.getCenter(); } } 67 Circle נרחיב את המחלקה מתודה המחזירה שטח המעגל public double area() { return _radius * _radius * Math.PI; } מתודה המחזירה היקף המעגל public double perimeter() { return _radius * 2 * Math.PI; } 68 מעבדה Circle נרחיב את המחלקה מתודה הבודקת אם המעגל מוכל כולו ברביע הראשון ?איך נדע public boolean isInFirstQuarter() { return (_center.getX() - _radius >=0 && _center.getY() - _radius >=0); } 69 2 מעבדה Circle נרחיב את המחלקה מתודה הבודקת אם נקודה היא בתוך המעגל ?מה צריך לבדוק public boolean isPointInside(Point p) { return (_center.distance(p) <_radius ); } 70 C#מערכים 71 מערך – הצהרה ויצירה ניתן להצהיר על מערך באופן הבא: ;int[] scores הצהרה כנ"ל מגדירה רק קיום של מערך ללא המערך עצמו scoresמצביע כעת לכתובת null אם רוצים לייצר מופע ( )instanceשל המערך נשתמש ב :new ;]scores = new int[10 זה יגדיר מערך של int 10 72 דוגמאות להצהרה ויצירה int[] prices = new int[500]; bool[] flags; int length = 20; flags = new bool[length]; char[] codes = new char[1750]; :מערך שגודלו נקבע בזמן ריצה int n = int.Parse(Console.ReadLine()); int[] a = new int[n]; 73 מערכים – גישה לתא בודד 9 8 7 6 5 4 3 2 1 0 79 87 94 82 67 98 87 81 74 91 scores מתיחסים לתא בודד במערך ע"י [ ] (סוגריים מרובעים) למשל ] scores[3מתיחס לתא הרביעי במערך ,וערכו .82 התא הראשון הוא ]scores[0 המערך הזה הוא של intולכן בתא בודד ניתן להשתמש כמו כל int אחר ;]int a = scores[2 ;mean = (scores[0] + scores[1])/2 ;)]Console.WriteLine ("Top = " + scores[5 74 אורך מערך Lengthמייצג את מספר האיברים במערך ;int a = scores.Length ל aיהיה הערך 10 ;)Console.WriteLine(scores.Length ידפיס 10 שימו לב: Lengthמכיל את מספר האיברים ולא האינדקס הכי גבוה! 75 האינדקס הכי גבוה הוא Length-1 רשימת אתחול ניתן ליצור מערך ולמלא בו ערכים ע"י שימוש ברשימת אתחול }int[] units = {147, 323, 89, 933, 540, 269, 97, 114 ;}'char[] letterGrades = {'A', 'B', 'C', 'D', 'F הערכים מופרדים ע"י פסיק גודל המערך נקבע לפי אורך הרשימה אין צורך להשתמש ב new אפשר להשתמש ברשימת אתחול רק בזמן הגדרת המערך 76 מערך -הדפסת כל האיברים יש לעבור על המערך (נעבור על כל התאים שלו) אורכו arr.Length נדפיס את התוכן של התא ;}int[] arr = {1,2,3,4,5 )for(int i =0; i<arr.Length; i++ { ;)]Console.WriteLine(arr[i } 77