תכנות מתקדם ב-Java/אובייקטים/תרגילים

על מנת לפתור תרגיל זה, יש להעתיק תחילה את הקבצים Item.java ו-Stock.java כפי שהם מופיעים בפרק. במידה ואתם עובדים עם סביבת עבודה, צרו פרוייקט שיכיל את שני הקבצים האלו. במידה ואתם עובדים משורת הפקודה, דאגו שהקבצים הנוגעים לתרגיל יופיעו באותה תיקייה, וההידור יתבצע באמצעות הפקודה javac *.java בהנחה שרק הקבצים הנוגעים לתרגיל נמצאים בתיקייה זו.

ממשק נוח יותר

עריכה

המשימה הראשונה היא לבנות דרך נוחה יותר להתעסק עם המחלקות שבנינו, וזאת באמצעות בנייה מחדש של הקובץ Grocery.java, בצורה נוחה למשתמש. בתחילה, תכניס התוכנית שני מוצרים למלאי (אפשר להשתמש בקוד המתאים שכבר נמצא בתוכנית, או לכתוב אותו מחדש). שנו את הקובץ, כך שאחרי הכנסת המוצרים, תציג התוכנית תפריט (טקסטואלי) שיאפשר לבעל המכולת לבחור אם להדפיס את המלאי הנוכחי, להדפיס את הערך הכולל של המוצרים, או לצאת. התוכנית תפעל עד שהמשתמש יבחר לצאת, ולאחר ביצוע כל פעולה - תדפיס מחדש את התפריט ותבקש מהמשתמש לבחור מה ברצונו לעשות. תפריט לדוגמה:

What do you want to do now?
1. Print stock
2. Calculate total stock value
3. Quit
Enter your choice:

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

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

פתרון
import java.util.Scanner;

// Grocery.java

public class Grocery {
	
	// Const variables
	private final static String MENU = 
		"What do you want to do now?\n"+
		"1. Print stock\n2. Calculate total stock value\n3. Quit\n";
	private final static String CHOICE = "Enter your choice: ";
	private final static String WRONG_CHOICE = "Wrong choice, choose again: ";
	private final static int PRINT_STOCK = 1;
	private final static int CALCULATE = 2;
	private final static int QUIT = 3;
	private final static int MAX_CHOICE = 3;
	private final static int MIN_CHOICE = 1;
	
	// Print the menu
	private static void printMenu() {
		System.out.print(MENU);
	}
	
	// Get the user choice. Check for legal input
	private static int getUserChoice() {
		Scanner s = new Scanner(System.in);
		System.out.print(CHOICE);
		int c = s.nextInt();
		while(c<MIN_CHOICE || c>MAX_CHOICE) {
			System.out.print(WRONG_CHOICE);
			c = s.nextInt();
		}
		return c;
	}
	
	private static void run(Stock st) {
		int userChoice = 0;
		while(userChoice != QUIT) {
			printMenu();
			userChoice = getUserChoice();
			switch(userChoice) {
			case PRINT_STOCK:
				st.printStock();
				break;
			case CALCULATE:
				System.out.println("Sum stock value: "+st.sumStock());
				break;
			}
		}
	}
	
	public static void main(String[] args) {
		// Build a stock object
		Stock stck = new Stock();
		// Add items to stock:
		Item it1 = new Item("Cheese","Smelly green cheese", 1.5);
		Item it2 = new Item("Tomato","Fresh tomato", 2.6);
		stck.addItem(it1, 2, 7);
		stck.addItem(it2, 3, 5);
		run(stck);
	}

}


חיפוש של מוצר

עריכה

בשלב זה ננסה לשפר את המחלקה Stock. הוסיפו למחלקה שיטה בשם Contains, המקבלת מחרוזת, ומחזירה "אמת" אם מוצר בשם זה קיים במלאי, ו"שקר", אם לא. כותרת השיטה היא

public boolean Contains(String item)

דאגו לטפל גם במצב בו אין במלאי אף מוצר, או שיש בו רק מוצר אחד, כך שהתוכנית לא תתמוטט בשום מצב. הוסיפו לתפריט אפשרות לבדוק אם מוצר קיים במלאי או לא. אם יכניס המשתמש אפשרות זו, הוא יתבקש לכתוב את שם המוצר שצריך לחפש, והתוכנית תדפיס אם המוצר נמצא במלאי או לא. רמז: כדי לבדוק אם שתי מחרוזות זהות, עדיף להשתמש בשיטה equals ולא בהשוואה רגילה. כלומר - if(str.equals(str2)) ולא if(str == str2).

פתרון
// Method to add to Stock.java
// Check if an item with the given name is in stock
public boolean Contains(String item) {
	String name;
	if(_item1 != null) { 
		name = _item1.getName();
		if(name.equals(item)) return true;
	}
	if(_item2 != null) {
		name = _item2.getName();
		if(name.equals(item)) return true;
	}
	return false;
}

// Grocery.java

import java.util.Scanner;

public class Grocery {
	
	// Const variables
	private final static String MENU = 
		"What do you want to do now?\n"+
		"1. Print stock\n2. Calculate total stock value\n"+
		"3. Search item\n4. Quit\n";
	private final static String CHOICE = "Enter your choice: ";
	private final static String WRONG_CHOICE = "Wrong choice, choose again: ";
	private final static String ITEM_FIND = "Enter item to search: ";
	private final static int PRINT_STOCK = 1;
	private final static int CALCULATE = 2;
	private final static int CONTAINS = 3;
	private final static int QUIT = 4;
	private final static int MAX_CHOICE = 4;
	private final static int MIN_CHOICE = 1;
	
	// Print the menu
	private static void printMenu() {
		System.out.print(MENU);
	}
	
	// Get the user choice. Check for legal input
	private static int getUserChoice() {
		Scanner s = new Scanner(System.in);
		System.out.print(CHOICE);
		int c = s.nextInt();
		while(c<MIN_CHOICE || c>MAX_CHOICE) {
			System.out.print(WRONG_CHOICE);
			c = s.nextInt();
		}
		return c;
	}
	
	// Get item name to search
	private static String getItemName() {
		System.out.print(ITEM_FIND);
		Scanner s = new Scanner(System.in);
		String str = s.next();
		return str;
	}
	
	private static void run(Stock st) {
		int userChoice = 0;
		while(userChoice != QUIT) {
			printMenu();
			userChoice = getUserChoice();
			switch(userChoice) {
			case PRINT_STOCK:
				st.printStock();
				break;
			case CALCULATE:
				System.out.println("Sum stock value: "+st.sumStock());
				break;
			case CONTAINS:
				String item = getItemName();
				System.out.println("Stock contains "+item+": "+st.Contains(item));
			}
		}
	}
	
	public static void main(String[] args) {
		// Build a stock object
		Stock stck = new Stock();
		// Add items to stock:
		Item it1 = new Item("Cheese","Smelly green cheese", 1.5);
		Item it2 = new Item("Tomato","Fresh tomato", 2.6);
		stck.addItem(it1, 2, 7);
		stck.addItem(it2, 3, 5);
		run(stck);
	}

}