English (United Kingdom) Hebrew

קורס:"Java"

שיעור 2: תכנות בסיסי

[ <<< הקודם ] [ תוכן עניינים ] [ הבא >>> ]

מתוך הספר: Java על כוס קפה       Java על כוס קפה
תוכן עניינים

תכנית ראשונה ב- Java

נכתוב תכנית Java בסיסית המדפיסה למסך את הפלט:

 
Hello Java!
 

קוד התכנית:

 
/** display "Hello Java!" to the standard output. */
public class Hello {
          public static void main(String[] args) {
                            System.out.println("Hello Java!")// display the text
          }
}
 

כדי להריץ את התכנית יש לבצע:

    1. הקלדה של הקוד בקובץ בשם Hello.java על ידי תכנית עריכה כלשהי.
    2. הידור הקובץ. בסביבת JDK מהדרים את התכנית כך:
 
javac Hello.java
 
    לאחר ההידור נוצר קובץ בשם Hello.class.
    3. הרצת התכנית. בסביבת JDK מריצים את התכנית כך:
 
java Hello
 

פלט התכנית:

 
Hello Java!
 

הסבר התכנית

התכנית כוללת מספר חלקים:

  • הגדרת המחלקה הראשית
  • הגדרת המתודה הראשית במחלקה
  • הערות ותיעוד

הגדרת המחלקה הראשית

הגדרת המחלקה Hello מבוצעת תוך שימוש במילה class , והגדרתה כ- public:

 
public class Hello {
}
 

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

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

שם קובץ התכנית חייב להיות בדיוק כשם המחלקה הראשית בקובץ, כלומר Hello.java (עם האות H גדולה, גם במערכת Windows!).

הגדרת המתודה הראשית במחלקה

המתודה הראשית נקראת main, בדומה לתכניות בשפות C/C++:

 
          public static void main(String[] args) {
                            System.out.println("Hello Java!")// display the text
          }
 

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

משמעות הכותרת של המתודה:

 
public static void main(String[] args)
 
    public - המתודה ניתנת לקריאה על ידי מתודות ממחלקות אחרות.
    static - ניתן לקרוא למתודה ללא הגדרת עצם מהמחלקה.
    void - המתודה לא מחזירה ערך כלשהו.
    String[] args - מערך מחרוזות הפרמטרים לתכנית - מקביל ל- argc, argv בתכניות C/C++.

החלק הנמצא בין הסוגריים המסולסלות

 
          System.out.println("Hello Java!")// display the text
 

הוא גוף המתודה, והוא כולל קריאה למתודה println של העצם out שבמחלקה System.  המתודה מדפיסה את המחרוזת הנתונה לה כפרמטר לפלט התקני, כלומר למסך. לאחר המחרוזת מודפס תו שורה חדשה. ההוראה System.out.print() ללא הסיומת “ln” מבצעת הדפסה דומה, אך ללא תוספת תו שורה חדשה.

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

הערות ותיעוד

בתכנית שתי צורות רישום הערות:

  1. הערות בצורה הנהוגה ב- C++, עם קו נטוי כפול:
 
          System.out.println("Hello Java!")// display the text
 

  2. הערות בתוך בלוק דמוי הערת C עם כוכבית כפולה בתחילתו, /** ...... */ :
 
/** display "Hello Java!" to the standard output. */
 
    הערות מסוג זה משמשות את הכלי ליצירת תיעוד אוטומטי javadoc. הערה זו לפני הגדרת מחלקה, מתודה ו/או משתנה תוכנס על ידי javadoc לקובץ תיעוד (HTML) של התכנית.
    

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

טיפוסים ומשתנים

נכתוב את התכנית הנ"ל מעט אחרת:

 
/** display "Hello Java!" to the standard output. */
public class Hello {
          public static void main(String[] args) {
               String s = "Hello Java!";
                   System.out.println(s)// display the text
          }
}
 

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

 
          String s = "Hello Java!";
 

בהצהרה על משתנה , ראשית מופיע הטיפוס (type) ואח"כ שם המשתנה. בדוגמא, הטיפוס הוא String והמשתנה הוא s.

משתנה הוא כתובת בזכרון שבו מאוחסן ערך המשתנה. בדוגמא הנ"ל, השם s מציין כתובת בזכרון בו נמצאת המחרוזת “Hello Java!".

ניתן לבצע פעולות שונות על המשתנה, אחת מהן היא להדפיסו על ידי ההוראה println()  שהכרנו קודם:

 
          System.out.println( s ); 
 

אנחנו יכולים להוסיף משתנים נוספים לתכנית ולבצע עליהם פעולות שונות. בסעיף הבא נראה תכנית כזו.

חישוב ממוצע של מספרים

בסעיף זה נכתוב תכנית שתחשב ותדפיס את הממוצע (מספר ממשי) של שלושה מספרים שלמים נתונים. קוד התכנית:

 
public class Average{
          public static void main(String[] args) {
                   int    num1, num2, num3;
                   float           avg;
 
                   num1 = 21;
                   num2 = 15;
                   num3 = 94;
 
                   avg = num1 + num2 + num3;
                   avg = avg / 3;
 
                   System.out.println("The average is: " + avg);
          }
}
 

פלט התכנית:

 
The average is: 43.333332
 

הסבר:

  • הצהרה על משתנים וטיפוסיהם - אנו שוב רואים הגדרת משתנים - הפעם מטיפוסים מספריים:
  - הטיפוס int (integer) משמש להצהרה על משתנה מטיפוס שלם:
 
          int num1, num2, num3;
 
  - הטיפוס float (floating point) מציין טיפוס ממשי בהצהרת המשתנה avg:
 
          float avg;
 
    avg הוא משתנה ממשי שבו תחושב תוצאת הסכום ולאחר מכן הממוצע.


טיפוסים נוספים לדוגמא הקיימים בשפה:

    byte - בית בודד
    char - תו unicode
    long - שלם ארוך
    double - ממשי בעל דיוק כפול

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

לאחר מתן הערכים למשתנים, סכומם מחושב ומוצב ל- avg :

 
          avg = num1 + num2 + num3;
 

הסימן "=" ב- C מציין פעולת הצבה (Assignment). תוצאת הביטוי שמימין לסימן מוצבת לתא בזיכרון שמשמאל לו. פעולה זו נקראת גם השמה.

שאלה: איך מסמנים שוויון בביטוי לוגי?

תשובה: על ידי שני תווים רצופים כנ"ל : "==". נרחיב בנושא בהמשך.

חישוב הממוצע מתבצע על ידי חילוק avg ב- 3 :

 
          avg = avg / 3;
 

avg / 3 מבצע פעולת חילוק וזו מוצבת ל- avg. אין כל בעיה בהימצאותו של avg משני צידי הוראת ההצבה - הצד הימני מחושב קודם, ולאחר מכן מוצבת התוצאה למשתנה שבצד השמאלי. ניתן לקצר את התכנית על ידי ביצוע פעולות החיבור והחלוקה בהוראה יחידה:

 
          avg = (num1 + num2 + num3) / 3;
 

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

 
          System.out.println("The average is: " + avg);
 

סימן החיבור המופיע בין המחרוזת ל- avg גורם לשירשור של avg לטקסט המחרוזת, ולכן מודפס המשפט השלם:

 
The average is: 43.333332
 

גירסה מקוצרת של התכנית

נכתוב שוב את התכנית, הפעם בגירסה מקוצרת:

 
public class Average{
          public static void main(String[] args) {
                   int  num1=21, num2=15, num3=94;
 
                   float avg = (num1 + num2 + num3) / 3.0F;
                   System.out.println("The average is: " + avg);
          }
}
 

  • המשתנים השלמים num1,num2 ו- num3 מאותחלים עוד בהגדרתם.
  • המשתנה הממשי avg מאותחל גם הוא בהגדרתו כתוצאת החלוקה של סכום 3 השלמים:
 
          avg = (num1 + num2 + num3) / 3.0F;
 
  - ביצענו חיבור בתוך סוגריים מכיוון שלאופרטור החילוק עדיפות על אופרטור החיבור. הסוגריים מציינים את סדר הפעולות הנדרש.
  - בחלוקה, ציינו שהמנה היא 3.0 ומסוג ממשי float על ידי 3.0F  : זאת מכיוון שלו חילקנו בשלם 3, היתה מתבצעת פעולת חילוק בשלמים, והתוצאה היתה 43!
    התוספת F מציינת עבור המהדר שמדובר בממשי רגיל מסוג float.

טיפוסים בסיסיים

ב- Java קיימים מספר טיפוסים בסיסיים המובאים בטבלה שבספר "Java על כוס קפה" בעמוד 32.

כל הטיפוסים המספריים (שלמים וממשיים) הם מסומנים (signed) - כלומר, יכולים לקבל הן ערכים חיוביים והן ערכים שליליים.

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

  • שימוש בתו:
 
        char c;
          c = 'a';
          System.out.print(c);
 

הטיפוס char הוא בן 16 סיביות ומייצג ערך Unicode, כך שניתן לייצג באמצעותו תווים מכל השפות הקיימות. לדוגמא, ניתן לכתוב:

 
          char c ='א'; 
          System.out.print(c);
           
 

מודפס:

 
א
 

  • שימוש בממשי:
 
          float f = 10.0;            // error: cannot convert from double to float
          f = 10.0F;                     // OK
          f = f - 0.5F;
          System.out.print(f);
 

מדוע מתקבלת הודעת שגיאה בשורה הראשונה ? ב- Java ליטרל (=ערך) ממשי הוא בברירת מחדל מסוג double, והמרה מרומזת של משתנה מטיפוס זה לטיפוס "קטן" יותר (float) אינה חוקית.

סימון הליטרל על ידי האות F או f מציינת שהוא מסוג float ולכן השורה השנייה תקינה.

הגדרת קבועים

קבועים הם תאי זכרון המחזיקים בערכים כלשהם, בדומה למשתנים, אולם בניגוד להם - לא ניתן לשנות ערך של קבוע לאחר שאותחל. ב- Java המילה השמורה final משמשת להגדרת קבועים. לדוגמא:

 
          final int N = 10;       // N is constant
 

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

מחרוזות

  • ב- Java קיימת מחלקה תקנית לייצוג מחרוזת בשם String. מחלקה זו כוללת מיגוון פעולות על מחרוזות כגון העתקה, שרשור, הדפסה, הצבה וכו'. דוגמא לשימוש ב- String:
 
public class StringApp{
          public static void main (String[] args) {
                   String s1 = "Hello";
                   String s2 = " Java";
                   
                   System.out.println(s1 + s2);   // prints "Hello Java"
                   System.out.println(s1 + s2 + "!");      // prints "Hello Java!"
                   String s3 = s1;                           // s3 = "Hello"
          }
}
 
  • בתכנית מגדירים מספר עצמים מסוג String, ומבצעים עליהם פעולות:
  - הצבת מחרוזת אחת לשנייה על ידי אופרטור ההצבה "="
  - שרשור מחרוזות על ידי אופרטור השרשור "+"
  - הדפסת המחרוזות על ידי המתודה println שהכרנו בתכניות הקודמות. מתודה זו מועמסת לקבל פרמטרים מסוגים שונים ובכללם עצמי String.

משפטי תנאי 

  • לעיתים תכופות מהלך התכנית נקבע באופן דינמי על פי הקלטים או חישובים מספריים. בנקודות מסוימות בתכנית נרצה לבצע קטע קוד כתלות בתנאי מסוים. בנקודות אחרות נרצה לבצע קטע קוד מספר פעמים. Java כוללת הוראות בקרה לקביעת מהלך התכנית:
  - משפט if-else לביצוע מותנה של הוראות
  - לולאות מסוגים שונים המשמשות לביצוע חוזר של קטע קוד

משפט if-else

  • משפטי התנאי מורכבים מההוראות if ו- if-else:
    תחביר הוראת if :

if( תנאי )

              הוראה/ות

    תחביר הוראת if-else :

if( תנאי )

                   הוראה/ות

else

                   הוראה/ות

בתוך גוף המשפט יכולה להופיע הוראה בודדת או מספר הוראות, מוקפות על ידי הסוגריים {}

  • במשפט if אם התנאי מתקיים, מבוצעת/ות ההוראה/ות שבגוף משפט התנאי, אחרת ממשיכים להוראה העוקבת למשפט התנאי.
  • במשפט if - else אם התנאי מתקיים, מבוצעת/ות ההוראה/ות שבגוף הוראת if, אחרת מבוצעת/ות ההוראה/ות שבגוף הוראת else. לאחר מכן ממשיכים להוראה העוקבת למשפט התנאי.

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

 
import java.util.*;
 
public class Test {
          public static void main(String[] args) {
                   int num1, num2;
 
                   System.out.print("Enter 2 integers: ");
                   Scanner sc = new Scanner(System.in);
                   num1 = sc.nextInt();
                   num2 = sc.nextInt();
 
                   System.out.print("|num1 - num2|= ");
                   if( num1 > num2 )
                            System.out.print(num1 - num2);
                   else
                            System.out.print(num2 - num1);
                            
          }
}
 

הרצת התכנית

דוגמא להרצת התכנית: בתחילת הריצה מודפס למסך

 
Enter 2 integers:
 


כעת נדרש להכניס קלט, נקליד למשל את המספרים 7 ו- 11:

 
Enter 2 integers: 7 11
 


כעת מתקבל פלט התכנית:

 
|num1 - num2|= 4
 

הסבר התכנית

התכנית מגדירה 2 משתנים מטיפוס שלם, int :

 
          int num1, num2;
 

לאחר מכן מתבקש המשתמש להקליד 2 מספרים שלמים, והם נקראים על ידי עצם Scanner לתוך num1, num2 - אנו לא נרד פה לפרטי פעולת הקלט, מכיוון שהיא מעט מורכבת. בשלב זה די בהבנה של הפעולות הנדרשות לביצוע הקלט:

    1. ייבוא הספריה java.util על ידי:
 
import java.util.*;
 
    2. ייצור עצם Scanner על בסיס System.in:
 
Scanner sc = new Scanner(System.in);
 

וכעת ניתן לקרוא מהקלט התקני מספרים שלמים (על ידי הקריאה nextInt()) מספרים ממשיים (על ידי הקריאה nextFloat()), מספרים ממשיים כפולים (על ידי קריאה ל- nextDouble()) וכו'.

בתכנית הדוגמא אנו קוראים שני מספרים שלמים כך:

 
                   Scanner sc = new Scanner(System.in);
                   num1 = sc.nextInt();
                   num2 = sc.nextInt();
 

לאחר מכן מבוצע משפט התנאי לבדיקה ולהדפסת הערך המקסימלי מביניהם כמשפט if-else:

 
                   System.out.print("|num1 - num2|= ");
                   if( num1 > num2 )
                            System.out.print(num1 - num2);
                   else
                            System.out.print(num2 - num1);
 

ביצוע מספר הוראות - בלוק

אם רוצים לבצע מספר הוראות בהוראת if או else, יש להקיפם בסוגריים מסולסלות, לדוגמא:

 
          if( num1 > num2 ) {
                   max = num1;
                   System.out.println(“num1 is greater than num2”);
          }
 
  - הביטוי num1 > num2 הוא ביטוי לוגי המחזיר ערך מטיפוס בוליאני - כלומר, true (אמת) או false (שקר).
  - סדרת הוראות מוקפת בסוגריים {} נקראת בלוק.

בדומה לאופרטור '>' המציין את היחס הלוגי "גדול מ-", בטבלה שבספר "Java על כוס קפה" בעמוד 38 מפורטים האופרטורים הלוגיים ומשמעותם.

לולאות

לולאה היא אמצעי לביצוע חוזר של פעולות מסוימות מספר פעמים, או כתלות בתנאי כלשהו.

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

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

  • while
  • do-while
  • for
  • for משופרת (החל מגירסה 5)

לולאת while

לולאת while משמשת לביצוע חוזר של הוראות כתלות בתנאי מסוים: תחביר הלולאה הוא

while(ביטוי לוגי) {

הוראות

}

כל עוד ערכו של הביטוי הלוגי אמת ההוראות שבגוף הלולאה מתבצעות. תרשים זרימה עבור ביצוע לולאת while:

תכנית הדוגמא הבאה מדפיסה את העצרת של מספר שלם n הנקרא מהקלט - כלומר מכפלת המספרים 1 עד n - על ידי שימוש בלולאת while:

 
import java.util.*;
 
public class Test {
          public static void main(String[] args) {
                   int n;
                   System.out.print("Enter a number: ");
                   Scanner sc = new Scanner(System.in);
                   n = sc.nextInt();
 
                   int i=1;
                   int factorial =1;
               while(i<=n) {
                       factorial  = factorial  * i;
                       i = i+1;
               }
                   System.out.print("factorial of " + n + " = " + factorial);
          }
}
 

הרצה לדוגמא של התכנית:

 
Enter a number: 10
factorial of 10 = 3628800
 


הסבר:

  - המספר n נקרא מהקלט על ידי :
 
                   n = sc.nextInt();
 
  - בשלב הבא מאותחל משתנה הלולאה, i, ל- 1:
 
                   int i=1;
 
  - גם תוצאת העצרת מאותחלת ל- 1 (מדוע?) לפני תחילת הלולאה:
 
                   int factorial =1;
 
  - לולאת ה- while מבוצעת כל עוד i קטן או שווה ל- n:
 
                   while(i<=n) {
                            factorial  = factorial  * i;
                            i = i+1;
                   }
 
    בכל איטרציה (=מחזור ביצוע גוף הלולאה) מוכפלת תוצאת העצרת (facotrial) במשתנה הלולאה i, הרץ על פני הערכים 1..n. בסוף הלולאה i מקודם ב- 1.

ביטויי הצבה וביטויים אריתמטיים מקוצרים - ניתן לקצר את קוד התכנית הקודמת במספר צורות:

  - במקום
 
                            factorial  = factorial  * i;
 
    ניתן לכתוב
 
                            factorial  *=  i;
 
    הסבר: משמעות הסימן x *= y היא "הכפל את x ב- y, והצב את המכפלה ב- x".
  - במקום הביטוי
 
                            i = i+1;
 
    ניתן לכתוב בקיצור
 
                            i ++;
 
    משמעות הביטוי x++ היא "קדם את x ב- 1".

לולאת do-while

לולאת do-while היא בעלת המבנה הבא:

do{

          הוראות

} while (תנאי);

ההוראות שבגוף הלולאה מתבצעות כל עוד התנאי מתקיים. תרשים זרימה של הלולאה:

מה ההבדל שבין לולאה זו לקודמת (while)? בלולאת while התנאי נבדק לפני ביצוע הלולאה, ולכן אם הוא אינו מתקיים הלולאה לא מבוצעת. בלולאת do-while גוף הלולאה ראשית מתבצע ואח"כ נבדק התנאי, ולכן מובטח לפחות ביצוע של חזרה אחת.

לדוגמא, את הלולאה לחישוב העצרת בתכנית הנ"ל ניתן לרשום גם כך:

 
          do {
                   factorial  = factorial  * i;
                   i = i+1;
          } while(i<=n) ;
 

לולאת for

לולאת for היא לולאה כללית נוחה מאוד לביצוע של הוראות מספר פעמים או כתלות בתנאי כלשהו. המבנה שלה מסתמך על הרעיון שכל לולאה מכילה בדרך כלל שלושה חלקים : 1) אתחול  2)בדיקת תנאי הלולאה  3) קידום צעד.

תחביר לולאת  for :

for ( <ביטוי 1> ; <ביטוי 2>  ; <ביטוי 3>) {

                  הוראות

}

בתוך הסוגריים שלאחר המלה for שלושה חלקים, מופרדים על ידי התו ";" :

    ביטוי 1 הוא אתחול המתבצע לפני תחילת הלולאה.
    ביטוי 2 הוא תנאי הלולאה - ביטוי לוגי שכל עוד ערכו אמת הלולאה מתבצעת.
    ביטוי 3 הוא קידום הצעד בלולאה.

ניתן לתאר את הוראת for על ידי אלגוריתם טקסטואלי:

בצע את ביטוי 1
כל עוד ערכו של ביטוי 2 אמת
          בצע את גוף הלולאה
          בצע את ביטוי 3

כמו כן ניתן לתאר את לולאת for על ידי תרשים זרימה:

לדוגמא, את התכנית לחישוב העצרת ניתן לכתוב כך על ידי לולאת for:

 
import java.util.*;
 
public class Test {
          public static void main(String[] args) {
                   int n;
                   System.out.print("Enter a number: ");
                   Scanner sc = new Scanner(System.in);
                   n = sc.nextInt();
 
                   int factorial=1;
               for(int i=1 ; i<=n; i++)
                       factorial = factorial  * i;
 
                   System.out.print("factorial of " + n + " = " + factorial);
          }
}
 

כפי שניתן לראות קיבלנו תכנית קצרה יותר ומובנית יותר. בלולאת for שבתכנית ביצענו את הגדרת מונה הלולאה ואיתחולו בביטוי 1 (אתחול הלולאה) על ידי :

 
                   for(int i=1 ; i<=n; i++)
 

ובביטוי 3, מבוצע קידום ההמשתנה. ביטוי 2 -  i<=n  - הוא תנאי הלולאה.

מכיוון שהלולאה קצרה היא כוללת רק הוראה יחידה, ולכן אין צורך בהגדרת בלוק על ידי "}" ו- "{".

מסקנה: הלולאה הנוחה ביותר לכתיבה היא for. לולאת for מכילה בכותרתה את שלושת השלבים הבסיסיים בטיפול בלולאה : אתחול, בדיקת תנאי להמשך הביצוע וקידום/שינוי משתנה.

השמטת חלקים בלולאת for

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

  • השמטת ביטוי האתחול. במקרה זה האתחול פשוט אינו מבוצע. לדוגמא:
 
for(; num< 5; num++) {
...
}
 
  • השמטת תנאי הלולאה. במקרה זה הלולאה היא אינסופית, לדוגמא:
 
for(i=0; ; i++)  { // forever 
...
}
 
  • השמטת קידום הצעד. לדוגמא:
 
for(i=0; i< 1000; ) {
          num = sc.nextInt();
          i = i + num;
          System.out.println("current iteration = "+ i);
}       
 
  • השמטת כל שלושת החלקים. הלולאה היא אינסופית :
 
for(;;)           { // forever 
...
}
         
 

דוגמא נוספת ללולאת for:

 
          for(char c='א'; c<='ת'; c++)
                   System.out.print(c);
          System.out.print('\n');
 

מודפס:

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


בדוגמא האחרונה המשתנה c הוגדר בכותרת הלולאה.



משפטי continue ו- break

כאשר נמצאים באמצע ביצוע של חזרה בלולאה מסוימת ניתן לסיימה בשני אופנים:

1. הוראת continue - הפסקת החזרה הנוכחית ומעבר לחזרה הבאה בלולאה. דוגמא :

 
for (int i=1; i<=n; i++) {
          if (i==3)
               continue;
          factorial = factorial  * i;
          
}
 

אם n=5 אזי יתבצע:  40 = 5 * 4 * 2 * 1

2. הוראת break - הפסקה מוחלטת של הלולאה ומעבר לביצוע ההוראה העוקבת ללולאה. דוגמא:

 
for (int i=1; i<=n; i++) {
          if (i==3)
               break;
          factorial = factorial  * i;
          
}
 

כעת יתבצע:     2 = 2 * 1.

משפט switch-case

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

  - מימוש האלגוריתם על ידי משפטי תנאי if-else הוא ארוך ומסורבל:
 
int month = sc.nextInt();
if (month == 1) { 
          System.out.println("January"); 
} 
else if (month == 2) { 
          System.out.println("February"); 
} . . .
 

משפט switch-case הוא תחליף טבעי וקריא יותר למימוש הסתעפות רב כוונית. תחביר המשפט:

switch( ביטוי ) {

          case  קבוע-שלם : הוראות

                             break;                            

          case  קבוע-שלם : הוראות

                             break;                            

          case  קבוע-שלם : הוראות

                             break;                            

          default: הוראות

}

במשפט switch הערך הנבדק מושווה לכל אחד מהערכים שבכניסות ה- case, החל מהראשון.

  - הכניסה הראשונה שנמצאת נכונה גורמת לביצוע סדרת ההוראות שבאותה כניסה. אם לא נמצאה אף כניסה מתאימה, נבחרת הכניסה default.

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

כאשר מזוהה כניסה נכונה בהוראת switch הביצוע נמשך גם לכניסות הבאות עד אשר מזוהה ההוראה break.

  - תכונה זאת נקראת falling-through.

נממש את התכנית על ידי משפט switch-case :

 
switch (month) {
            case 1:     System.out.println("January"); 
                            break;
            case 2:     System.out.println("February"); 
                            break;
                    ...
            case 11:   System.out.println("November"); 
                            break;
            case 12:  System.out.println("December"); 
                            break;
          default:     System.out.println("This is not a valid month!"); 
}
 

כפי שכבר הוסבר, כאשר מזוהה כניסה נכונה בהוראת switch הביצוע נמשך גם לכניסות הבאות עד אשר מזוהה ההוראה break.

לכן, אם למשל נרצה להדפיס את מספר הימים שיש בחודש הנתון, בהינתן ש- month הוא מספר החודש ו- year הוא השנה, נבצע:

 
int month = sc.nextInt();   // read month
int year= sc.nextInt();        // read year
int days;
switch (month) {
            case 1:
            case 3:
            case 5:
            case 7:
            case 8:
            case 10:
            case 12:
                days = 31;
                break;
            case 4:
            case 6:
            case 9:
            case 11:
                days = 30;
                break;
            case 2:
                if ( ((year % 4 == 0) && !(year % 100 == 0))
                     || (year % 400 == 0) )
                    days = 29;
                else
                    days = 28;
                break;
          default: System.out.println("This is not a valid month!"); 
                     days=0;
        }
        System.out.println("Number of Days = " + days);
 

מתודות (Methods)

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

כתוב/י תכנית שתדפיס את כל החזקות החד ספרתיות (המספרים 0..9) של 2 ושל 3 בטבלה.

מטרת המשימה היא להדפיס את הטבלה הבאה:

 
i    power(2,i)    power(3,i)
-    ----------    ----------    
0    1             1
1    2             3
2    4             9
3    8             27
4    16            81
5    32            243
6    64            729
7    128           2187
8    256           6561
9    512           19683
 

במבט ראשון, נראה שכדאי לפרק את המשימה על ידי לולאה:

הדפס כותרות לטבלה
בלולאה עם אינדקס i  מ- 0 עד 9 בצע:
          חשב את החזקה של 2 ב- i (res1)
          חשב את החזקה של 3 ב- i (res2)
          הדפס שורה בטבלה - i, res1  ו- res2

כעת יש לפרק את הוראות הלולאה הדורשות את חישוב החזקה: נבצע זאת על ידי לולאה פנימית העוברת על המספרים i..1 ומבצעת הכפלה של 2 או 3 כמספר החזרות.

האלגוריתם המלא:

משתנים: i,j - אינדקסים בלולאות, res1, res2 - משתנים לחישוב החזקות
אתחול:res1 <-- 1,  res2 <-- 1
הדפס כותרות לטבלה
בלולאה עם אינדקס i  מ- 0 עד 9 בצע:
          בלולאה עם אינדקס j  מ- 1 עד i  בצע:
                     res1 <-- res1*2
          בלולאה עם אינדקס j  מ- 1 עד i  בצע:
                     res2 <-- res2*3
          הדפס שורה בטבלה - i, res1  ו- res2

                       

כפי שניתן לראות, res1 ו- res2 מטופלים באופן דומה לחישוב החזקה ה- i-ית של 2 ו- 3 בהתאמה. כל אחד מהם מוכפל j פעמים בבסיס החזקה (2 או 3). בכדי לבצע את חישוב החזקה נכון יש לאתחל את res1 ו- res2  ל- 1.

מהם חסרונות פירוק זה?

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

הגדרת משימה עצמאית על ידי מתודה

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

מתודה power  לחישוב חזקה:

פרמטרים: base - בסיס החזקה,  n - מעריך החזקה
אתחול: result <-- 1
בלולאה עם אינדקס i  מ- 1 עד n  בצע:
              result <-- result * base
החזר את result

כעת ניתן להשתמש במתודה שהגדרנו power על ידי ציון שמה והעברת פרמטרים מתאימים. לדוגמא, בכדי לחשב את החזקה של 2 ב- 5 נכתוב power(2,5). אם נרצה לקבל את התוצאה במשתנה res למשל, נכתוב:

          res1 <-- power(2,5)

נגדיר את אלגוריתם המשימה הכללית תוך שימוש במתודה שהגדרנו power :

משתנים: i - אינדקס הלולאה, res1, res2 - משתני תוצאות החזקות
הדפס כותרות לטבלה
בלולאה עם אינדקס i  מ- 0 עד 9 בצע:
               res1 <-- power(2,i)
               res2 <-- power(3,i)
               הדפס שורה בטבלה - i, res1  ו- res2

מנגנון המתודות

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

לדוגמא, נניח שיש לנו תכנית שבה קיימות המתודות h(), g(), f(), main(). main מבצעת קריאה ל- f ו- f קוראת למתודות g ו- h :

לאחר שהמתודה הנקראת מסתיימת, חוזר הביצוע למתודה הקוראת, אל ההוראה העוקבת להוראת הקריאה למתודה.

ניתן להעביר מידע ביו המתודה הקוראת לנקראת: המתודה הקוראת מעבירה רשימת פרמטרים (או ארגומנטים) למתודה הנקראת לצורך העיבוד.

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

הגדרת מתודה

המבנה התחבירי של הגדרת מתודה:

(<הצהרת פרמטרים>)  <שם-המתודה> < טיפוס-ערך-המוחזר> }

<הגדרות טיפוסים, קבועים ומשתנים>    

<הוראות>      

{

הגדרות מתודות יכולות להיות בסדר כלשהו.

כתכנית דוגמא, נממש את האלגוריתם שהגדרנו בתחילת סעיף זה, להדפסת החזקות של 2 ו- 3. התכנית הכוללת מובאת בספר "Java על כוס קפה" בעמוד 51.

פלט התכנית:

 
i    power(2,i)    power(3,i)
-    ----------    ----------    
0    1             1
1    2             3
2    4             9
3    8             27
4    16            81
5    32            243
6    64            729
7    128           2187
8    256           6561
9    512           19683
 

הסבר

  • בהגדרת המתודה power
 
public static int power (int base, int n) {
          int result=1;
          ...
}
 

     ציינו ש- :

  - היא  public ו- static כמו main - כרגע אין לנו צורך בהבנת מציינים אלו.
  - המתודה מקבלת שני פרמטרים מטיפוס שלם : base ו- n.
  - המתודה מחזירה ערך מטיפוס שלם.
  - בתוך המתודה ניתן להגדיר משתנים מקומיים (result) לצורך חישובי ביניים.
  - גוף המתודה כולל את חישוב החזקה על ידי לולאת for:
 
          for (int i=1; i<=n; ++i)
                   result = result * base;
 
  - התוצאה המוצבת במשתנה result מוחזרת בסוף המתודה על ידי ההוראה:
 
           return result ;
 
  • השימוש במתודה power בתוך main :
  - הקריאה למתודה power מתבצעת פעמיים בכל ביצוע של הלולאה:
 
          res1 = power(2,i);
          res2 = power(3,i);
 
    בכל קריאה מועברים 2 פרמטרים למתודה ומוחזר ערך התוצאה, שמוצב במתודה הקוראת למשתנה המתאים.

קריאה ישירה למתודה בהוראת ההדפסה

נכתוב את המתודה הראשית main שוב באופן מקוצר:

 
public static void main(String[] args)  {
          System.out.printf("%-4s %-13s %-13s%n", "i", "power(2,i)", "power(3,i)");
          System.out.printf("%-4s %-13s %-13s%n", "-", "----------", "----------");
          for (int i=0; i<10; ++i) {
                   System.out.printf("%-4d %-13d %-13d%n", i, power(2,i), power(3,i));
          }
}
 

הפעם נקראת המתודה power בתוך הוראת ההדפסה, ותוצאתה מועברת ישירות כפרמטר למתודה printf לצורך הדפסה:

 
                   System.out.printf("%-4d %-13d %-13d%n", i, power(2,i), power(3,i));
 

בגרסה זו של המתודה main אין צורך בהגדרת המשתנים res1, res2.

הכרזה על הפרמטרים

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

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

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

לדוגמא, אם מהמתודה main() ננסה לקרוא למתודה power() עם ערך ממשי, נקבל שגיאת הידור:

 
          int i = 3;
          double d = 2.0;
 
          int res = power(i,d); // error: trying to convert double to int
 

בקריאה למתודה power המהדר יגלה אי-התאמה בפרמטר השני בין הטיפוס האקטואלי לבין הטיפוס הפורמלי: נסיון להמיר double ל- int הוא שגיאה עקב אובדן מידע. לעומת זאת, הפעולה ההפוכה - המרת שלם לממשי - מותרת, מכיוון שאין אובדן של מידע.

ערך מוחזר

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

בדוגמא הקודמת טיפוס הערך המוחזר של המתודה power() הוא שלם (int), והיא מחזירה את תוצאת החזקה, המוצבת במתודה הקוראת למשתנה מקומי שלה:

הערך המוחזר מוחזר על ידי ההוראה return. הוראה זו גם גורמת לסיום הביצוע של המתודה וחזרה למתודה הקוראת.

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

המרת הערך המוחזר

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

 
public static float max(float x, float y) {
          if(x>y)
                   return x;
          else
                   return y;
}
 
public static void main(String[] args)  {
          float  a=9.4F, b=34.8F;
          int i;
        i = max(a,b)// error: cannot convert float to int
}
 

 ניתן, אם רוצים, לבצע המרה מפורשת באופן הבא:

 
        i = (int) max(a,b)// Ok now
 

משמעות ההמרה המפורשת היא שהמתכנת מודע לפעולת הקיצוץ שעלולה להתבצע והוא מוכן לקבלה. לכן הפעולה עתה היא חוקית.

המתודה main

main היא מתודה כמו כל מתודה אחרת הנקראת על ידי מכונת Java בתחילת הריצה של היישום, מתוך שם המחלקה שנבחרה בהרצה.

לדוגמא, כאשר התכנית האחרונה, Functions, מהודרת ומורצת

 
javac Functions.java          // compile
java Functions           // run
 

המכונה המדומה של Java מתחילה את ריצת היישום החל מהמתודה main() הנמצאת במחלקה Functions. אם לא נמצאה מתודה כזו, המוכרזת בדיוק כך

 
        public static void main(String[] args)
 

תתקבל הודעת שגיאה.

העמסת מתודות (Method Overloading)

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

לדוגמא, ניתן להגדיר בתכנית הנ"ל שתי מתודות max(): אחת המקבלת שני פרמטרים ומחזירה את המקסימום מביניהם, והשניה מחזירה את המקסימום מבין 3 מספרים שנתונים לה כפרמטרים:

 
public class Test {
        public static float max(float x, float y) {
                   if(x>y)
                            return x;
                   else
                            return y;
          }
        public static float max(float x, float y, float z) {
                   return max( max(x,y), z);
          }
          
          public static void main(String[] args) {
                   float f1=-103.12F , f2=99.9F , f3=113.3F;
                   System.out.println("max(f1,f2) = " + max(f1,f2));
                   System.out.println("max(f1,f2,f3) = " + max(f1,f2,f3));
          }
}
 

פלט התכנית :

 
max(f1,f2) = 99.9
max(f1,f2,f3) = 113.3
 

מערכים

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

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

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

תחביר: הגדרת מערך דומה להגדרת משתנה, בתוספת סוגריים מרובעות כך:

<טיפוס-איבר>  <שם-המערך> [ ];

או גם כך:

<טיפוס-איבר> [ ] <שם-המערך> ;

לדוגמא, הגדרת מערך שלמים :

int   integers [] ;

הקצאת איברי המערך מבוצעת על ידי ההוראה new כך:

int integers [] = new int[5];

כאן ייצרנו את המערך כמערך בגודל של 5 שלמים.

במערך מגודל n, הערכים מאוחסנים במערך החל מאינדקס 0 ועד ל- n-1. לכן הגישה לאיברי המערך integers תהיה על פי התרשים הבא:

4

3

2

1

0

integers[]  =



הגישה לאיבר באינדקס i במערך מבוצעת על ידי שם המערך, בתוספת האינדקס בסוגריים:

 <שם-המערך>[i]

לדוגמא, נציב לאיבר הראשון (אינדקס 0) ערך 23, ולאיבר האחרון (אינדקס 4) ערך 11:

 
integers[0] = 23;
integers[4] = 11;
 

באופן דומה, נדפיס את האיבר שבאינדקס 3 (האיבר הרביעי) כך:

 
System.out.println("integers[3] = " + integers[3]);
 

נקדם הערך שבתא האחרון ב- 1:

 
integers[4]++;   // now integers[4] is 12
 

יש לשים לב, שבניגוד לשפות C/C++, ב- Java לא ניתן להקצות מערך באופן סטטי על ידי ציון גדלו - זוהי שגיאת קומפילציה:

 
int int_array[10]; // error!
 

אך בדומה ל- C/C++ ניתן להקצותו על ידי אתחול איבריו. דוגמאות:

 
char char_array[] = {'a', 'ב', 'c'};                            // chars array
String  str_array[] = {"black", "white", "red", "green"}; // Strings array
 

ניתן להגדיר מערך דו-ממדי על ידי שימוש כפול בסימן "[ ]" כך:

 
long  array_2D[][] = new long[10][5]; // 2D array of longs
 

זהו מערך של 10 שורות ו- 5 עמודות. למעשה, ניתן בצורה זו להגדיר מערכים רב מימדיים מכל מימד שהוא.

גישה לאיברי המערך

פעולות על מערכים מבוצעות במקרים רבים בלולאות. במעבר על איברי המערך בלולאה נוח להשתמש בתכונה length שלו, לדוגמא:

 
int [] int_array = new int[10];
for(int i=0; i<int_array.length; i++) {
          int_array[i] = i;
}
 

ניתן לייעל את ביצוע הלולאה על ידי קריאת אורך המערך בראשית הלולאה:

 
int [] int_array = new int[10];
for(int i=0, limit = int_array.length;  i< limit;  i++) {
          int_array[i] = i;
}
 

כעת, המכונה המדומה (VM) אינה ניגשת לתכונה length בראשית כל איטרציה של הלולאה.

ולהלן דוגמא לביצוע לולאה כפולה על איברי מערך דו-ממדי :

 
          long array_2D[][] = new long[10][5]; // 2D array of longs
          for(int i=0; i<array_2D.length; i++) {
                   for(int j=0; j<array_2D[i].length; j++) {
                            array_2D[i][j] = i+j;
                            System.out.print(array_2D[i][j] + "\t");
                   }
                   System.out.println();
          }
 

והפלט:

 
0       1       2       3       4
1       2       3       4       5
2       3       4       5       6
3       4       5       6       7
4       5       6       7       8
5       6       7       8       9
6       7       8       9       10
7       8       9       10      11
8       9       10      11      12
9       10      11      12      13
 


יש לשים לב לשימוש הכפול שנעשה בתכונה length, פעם כמימד השורות במערך ופעם כמימד העמודות.

חריגה מגבולות המערך 

ב- Java, בניגוד ל- C/C++, נבדקות חריגות מגבולות המערך על ידי המכונה הוירטואלית. במידה ויש חריגה כזו, מופעל מנגנון "זריקת חריגות" (Exceptions) ו"נזרקת" חריגה מתאימה.

לדוגמא, אם הוגדר והוקצה המערך הבא

 
int [] int_array = new int[10];
 

נסיון לכתוב לאיבר באינדקס 10

 
int_array[10] = 5;  
                   // Runtime exception: ArrayIndexOutOfBoundsException
 

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

לולאת for משופרת (החל מגירסה 5)

לולאת for בעלת תחביר נוח פותחה עבור מערכים ועבור מחלקות אוסף. היא מהווה תחליף נוח על פני לולאות for ו- while המסורתיות.

כדוגמא, נתבונן במתודה הבאה, המחשבת את סכום איברי מערך שלמים המועבר לה כפרמטר:

 
int sum(int[] a) { 
          int result = 0; 
          for(int i=0; i<a.length; i++)
                   result += i; 
          return result; 
}
 

הערה: מתודה המקבלת מערך כפרמטר לא מציינת את גדלו, רק מכריזה עליו.

ניתן לרשום מתודה זו תוך שימוש בלולאת for המשופרת כך:

 
int sum(int[] a) { 
          int result = 0; 
          for (int i : a) 
                   result += i; 
          return result; 
}
 

תחביר לולאת for המשופרת הוא כלהלן:

          for(<type> x : <sequence>)

                   <use x as the current element>

בכל איטרציה בלולאה, x משמש כמייצג את האלמנט המתאים בסדרה sequence. זו האחרונה יכולה להיות מערך,  או במקרה הכללי מחלקת אוסף - כפי שנראה בפרק Error! Reference source not found..

הפרמטרים לתכנית

הפרמטרים לתכנית מועברים כמערך מחרוזות המצויין על ידי הפרמטר args שבמתודה main():

 
public static void main (String[] args)
 

לדוגמא, אם שם המחלקה הראשית בתכנית הוא Prog, והיא הופעלה משורת הפקודה כך:

 
java          Prog          hello 23.44   12
 

אזי args יהיה מערך באורך 3 ויכיל את המחרוזות הבאות כך:

 
{ “hello”, “23.44”, “12}
 

לדוגמא, התכנית הבאה קוראת את הפרמטרים המועברים אליה ומדפיסה אותם:

 
class Prog {
          public static void main (String[] args) {
                   for(String arg : args)
                            System.out.println(arg);
          }
}
 

נהדר את התכנית כך:

 
javac        Prog .java          // creates  Prog.class
 

וכעת נריץ אותה, תוך העברת פרמטרים בשורת הפקודה:

 
java          Prog          hello  23.44  12
 

פלט התכנית:

 
hello
23.44
12
 

מחרוזת כמערך

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

 
          String abcdef = “abcdef”;
 

ניתן להפעיל עליה שירותים שונים של המחלקה String:

  • indexOf(ch) - מחזירה את האינדקס של תו מסויים במחרוזת. מוחזר האינדקס של המופע הראשון של התו שהתגלה בסריקה משמאל לימין, על בסיס ספירה 0 (בדומה למערך). אם לא נמצא התו - מוחזר הערך -1.
  • substring(i,j) - מחזירה תת-מחרוזת שמורכב מהתווים שבאינדקס i על אינדקס j (לא כולל).

לדוגמא:

 
          String cd = abcdef.substring(2,4);              // cd =“cd”
          String b = abcdef.substring(1, 2);   // b =“b”
          char c = abcdef.charAt(2);                // c = “c”
          System.out.println(abcdef.indexOf(c)); // print: 2
 

סיכום

  • יישום בסיסי ב- Java כולל מחלקה ראשית המוגדרת כ- public והוא יכול לכלול מחלקות נוספות. המחלקה הראשית חייבת להכיל את המתודה main בעלת הכותרת:
 
public static void main(String args[])
 
  • הטיפוסים הבסיסיים ב- Java כוללים ייצוג לשלם, ממשי, לתתי סוגים שלהם ולתו.
  • מחרוזת מיוצגת על ידי מחלקה מובנית ב- Java בשם String. מוגדרים עליה אופרטורים נוחים כגון: הצבה (=), שרשור (+) ובדיקת שוויון מצביעים (==). לצורך בדיקת שוויון של תוכן שתי מחרוזות יש להשתמש במתודה equals() .
  • מתודות הן מנגנון המאפשר חלוקה של משימה מורכבת למשימות קטנות יותר ועצמאיות. חלוקה של התכנית למתודות מאפשרת פיתוח מודולרי והדרגתי של התכנית.
  - אחת המתודות במחלקה הראשית חייבת להיותmain  - זו המתודה שממנה מתחיל ביצוע התכנית.
  - המתודה הקוראת מעבירה רשימת פרמטרים (ארגומנטים) למתודה הנקראת. הפרמטרים המועברים (פרמטרים אקטואליים) משוכפלים במתודה הנקראת (פרמטרים פורמליים), תוך ביצוע המרה מרומזת או מפורשת במידת הצורך.
  - כאשר המתודה הנקראת מסתיימת, היא מעבירה את הערך המוחזר למתודה הקוראת. גם בקבלת הערך המוחזר תתכן המרת טיפוס - מפורשת או מרומזת.
  • מערך ב- Java הוא עצם ולא רק סדרת תאים בזכרון. יש להקצות אותו בפירוש (על ידי new) וכן ניתן להשתמש בתכונה length שלו המחזיקה את ארכו.



[ <<< הקודם ] [ תוכן עניינים ] [ הבא >>> ]