El-Shorouk Academy Higher Institute for Computer Information Technology Computer Science Department Acad. Year: 2010 / 2011 Term : 1st Year : 3rd Professor :Mohammed Zeweedy Advanced Programming Using (Java) Section (5) public class Bicycle { // the Bicycle class has three fields public int gear; public int speed; // the Bicycle class has one constructor public Bicycle(int startCadence, int startSpeed, int startGear) { gear = startGear; cadence = startCadence; speed = startSpeed; } // the Bicycle class has four methods public void setCadence(int newValue) { cadence = newValue; } public void setGear(int newValue) { gear = newValue; } public void applyBrake(int decrement) { speed -= decrement; } public void speedUp(int increment) { speed += increment; } } You can use the Bicycle constructor to set the id instance variable and increment the numberOfBicycles class variable: public class Bicycle{ private private private private private int cadence; int gear; int speed; int id; static int numberOfBicycles = 0; public Bicycle(int startCadence, int startSpeed, int startGear){ gear = startGear; cadence = startCadence; speed = startSpeed; // increment number of Bicycles and assign ID number id = ++numberOfBicycles; } // new method to return the ID instance variable public int getID() { return id; } Class Methods The Java programming language supports static methods as well as static variables. Static methods, which have the static modifier in their declarations, should be invoked with the class name, without the need for creating an instance of the class, as in ClassName.methodName(args) Note: You can also refer to static methods with an object reference like instanceName.methodName(args) but this is discouraged because it does not make it clear that they are class methods. A common use for static methods is to access static fields. For example, we could add a static method to the Bicycle class to access the numberOfBicycles static field: public static int getNumberOfBicycles() { return numberOfBicycles; } Not all combinations of instance and class variables and methods are allowed: Instance methods can access instance variables and instance methods directly. Instance methods can access class variables and class methods directly. Class methods can access class variables and class methods directly. Class methods cannot access instance variables or instance methods directly—they must use an object reference. Also, class methods cannot use the this keyword as there is no instance for this to refer to. Constants The static modifier, in combination with the final modifier, is also used to define constants. The final modifier indicates that the value of this field cannot change. For example, the following variable declaration defines a constant named PI, whose value is an approximation of pi (the ratio of the circumference of a circle to its diameter): static final double PI = 3.141592653589793; Constants defined in this way cannot be reassigned, and it is a compile-time error if your program tries to do so. By convention, the names of constant values are spelled in uppercase letters. If the name is composed of more than one word, the words are separated by an underscore (_). Note: If a primitive type or a string is defined as a constant and the value is known at compile time, the compiler replaces the constant name everywhere in the code with its value. This is called a compile-time constant. If the value of the constant in the outside world changes (for example, if it is legislated that pi actually should be 3.975), you will need to recompile any classes that use this constant to get the current value. The Bicycle Class After all the modifications made in this section, the Bicycle class is now: public class Bicycle{ private int cadence; private int gear; private int speed; private int id; private static int numberOfBicycles = 0; public Bicycle(int startCadence, int startSpeed, int startGear){ gear = startGear; cadence = startCadence; speed = startSpeed; id = ++numberOfBicycles; } public int getID() { return id; } public static int getNumberOfBicycles() { return numberOfBicycles; } public int getCadence(){ return cadence; } public void setCadence(int newValue){ cadence = newValue; } public int getGear(){ return gear; } public void setGear(int newValue){ gear = newValue; } public int getSpeed(){ return speed; } public void applyBrake(int decrement){ speed -= decrement; } public void speedUp(int increment){ speed += increment; } } Nested Classes The Java programming language allows you to define a class within another class. Such a class is called a nested class and is illustrated here: class OuterClass { ... class NestedClass { ... } } Terminology: Nested classes are divided into two categories: static and non-static. Nested classes that are declared static are simply called static nested classes. Non-static nested classes are called inner classes. class OuterClass { ... static class StaticNestedClass { ... } class InnerClass { ... } } A nested class is a member of its enclosing class. Non-static nested classes (inner classes) have access to other members of the enclosing class, even if they are declared private. Static nested classes do not have access to other members of the enclosing class. As a member of the OuterClass, a nested class can be declared private, public, protected, or package private. Why Use Nested Classes? There are several compelling reasons for using nested classes, among them: It is a way of logically grouping classes that are only used in one place. It increases encapsulation. Nested classes can lead to more readable and maintainable code. Logical grouping of classes—If a class is useful to only one other class, then it is logical to embed it in that class and keep the two together. Nesting such "helper classes" makes their package more streamlined. Increased encapsulation—Consider two top-level classes, A and B, where B needs access to members of A that would otherwise be declared private. By hiding class B within class A, A's members can be declared private and B can access them. In addition, B itself can be hidden from the outside world. More readable, maintainable code—Nesting small classes within top-level classes places the code closer to where it is used. Static Nested Classes As with class methods and variables, a static nested class is associated with its outer class. And like static class methods, a static nested class cannot refer directly to instance variables or methods defined in its enclosing class — it can use them only through an object reference. Problem on classes: (The Fan class) Design a class named Fan to represent a fan. The class contains: Three constants named SLOW, MEDIUM, and FAST with values 1, 2, and 3 to denote the fan speed. An int data field named speed that specifies the speed of the fan (default SLOW). A boolean data field named on that specifies whether the fan is on (default false). A double data field named radius that specifies the radius of the fan (default 5). A string data field named color that specifies the color of the fan (default blue). A no-arg constructor that creates a default fan. The accessor and mutator methods for all four data fields. A method named toString() that returns a string description for the fan. If the fan is on, the method returns the fan speed, color, and radius in one combined string. If the fan is not on, the method returns fan color and radius along with the string "fan is off" in one combined string. Implement the class. Write a test program that creates two Fan objects. Assign maximum speed, radius 10, color yellow, and turn it on to the first object. Assign medium speed, radius 5, color blue, and turn it off to the second object. Display the objects by invoking their toString method. Problem Solution: public class Exercise7_2 { public static void main(String[] args) { Fan1 fan = new Fan1(); fan.setSpeed(Fan1.FAST); fan.setRadius(10); fan.setOn(true); fan.setColor("yellow"); System.out.println(fan.toString()); } } class Fan1 { public static int SLOW = 1; public static int MEDIUM = 2; public static int FAST = 3; private int speed = SLOW; private boolean on = false; private double radius = 5; private String color = "white"; public Fan1() { } public int getSpeed() { return speed; } public void setSpeed(int speed) { this.speed = speed; } public boolean isOn() { return on; } public void setOn(boolean trueOrFalse) { this.on = trueOrFalse; } public double getRadius() { return radius; } public void setRadius(double radius) { this.radius = radius; } public String getColor() { return color; } public void setColor(String color) { this.color = color; } public String toString() { return "speed " + speed + "\n" + "on " + on + "\n" + "radius " + radius + "\n" + "color " + color + "\n"; } } Problem Description: (The Stock class) Design a class named Stock that contains: A string data field named symbol for the stock's symbol. A string data field named name for the stock's name. A double data field named previousClosingPrice that stores the stock price for the previous day. A double data field named currentPrice that stores the stock price for the current time. A constructor that creates a stock with specified symbol and name. The accessor methods for all data fields. The mutator methods for previousClosingPrice and currentPrice. A method named changePercent() that returns the percentage changed from previousClosingPrice to currentPrice. Implement the class. Write a test program that creates a Stock object with the stock symbol SUNW, the name Sun Microsystems Inc, and the previous closing price of 100. Set a new current price to 90 and display the price-change percentage. Problem Solution: public class Exercise7_4 { public static void main(String[] args) { Stock stock = new Stock("SUNW", "Sun MicroSystems Inc."); stock.setPreviousClosingPrice(100); // Set current price stock.setCurrentPrice(90); // Display stock info System.out.println("Previous Closing Price: " + stock.getPreviousClosingPrice()); System.out.println("Current Price: " + stock.getCurrentPrice()); System.out.println("Price Change: " + stock.changePercent()); } } class Stock { private String symbol; private String name; private double previousClosingPrice; private double currentPrice; public Stock() { } public Stock(String symbol, String name) { this.symbol = symbol; this.name = name; } public String getSymbol() { return symbol; } public String getName() { return name; } public double getPreviousClosingPrice() { return previousClosingPrice; } public double getCurrentPrice() { return currentPrice; } public void setSymbol(String symbol) { this.symbol = symbol; } public void setName(String name) { this.name = name; } public void setPreviousClosingPrice(double price) { this.previousClosingPrice = price; } public void setCurrentPrice(double price) { this.currentPrice = price; } public double changePercent() { return (currentPrice - previousClosingPrice) / previousClosingPrice; } } Problem Description: (Displaying the prime factors) Write a program that receives a positive integer and displays all its smallest factors in decreasing order. For example, if the integer is 120, the smallest factors are displayed as 5, 3, 2, 2, 2. Use the StackOfIntegers class to store the factors (e.g., 2, 2, 2, 3, 5) and retrieve and display them in reverse order. Problem Solution: import javax.swing.*; public class Exercise7_12 { public static void main(String[] args) { StackOfIntegers stack = new StackOfIntegers(2); // Prompt the user to enter an integer String intString = JOptionPane.showInputDialog(null, "Enter an integer:", "Exercise7_8 Input", JOptionPane.QUESTION_MESSAGE); // Convert string to int int number = Integer.parseInt(intString); // Find and store all the smallest factors of the integer int factor = 2; while (factor <= number) { if (number % factor == 0) { number = number / factor; stack.push(factor); } else { factor++; } } // Display factors System.out.println("The factors for " + number + " is"); while (!stack.empty()) { System.out.print(stack.pop() + " "); } } } Problem Description: (The Tax class) Design a class named Tax to contain the following instance data fields: int filingStatus: One of the four tax filing statuses: 0 — single filer, 1 — married filing jointly, 2 — married filing separately, and 3 — head of household. Use the public static constants SINGLE_FILER (0), MARRIED_JOINTLY (1), MARRIED_SEPARATELY (2), HEAD_OF_HOUSEHOLD (3) to represent the status. int[][] brackets: Stores the tax brackets for each filing status. double[] rates: Stores tax rates for each bracket. double taxableIncome: Stores the taxable income. Provide the get and set methods for each data field and the getTax() method that returns the tax. Also provide a noarg constructor and the constructor Tax(filingStatus, brackets, rates, taxableIncome). Implement the class. Write a test program that uses the Tax class to print the 2001 and 2002 tax tables for taxable income from $50,000 to $60,000 with intervals of $1,000 for all four statuses. The tax rates for the year 2002 were given in Table. The tax rates for 2001 are shown in Table. Problem Solution: public class Exercise7_14 { public static void main(String[] args) { int[][] bracketsFor2001 = { {27050, 65550, 136750, 297350}, // Single filer {45200, 109250, 166500, 297350}, // married filing jointly {22600, 54625, 83250, 148675}, // married filing separately {36250, 93650, 151650, 297350} // head of household }; double[] ratesFor2001 = {0.15, 0.275, 0.305, 0.355, 0.391}; int[][] bracketsFor2002 = { {6000, 27950, 67700, 141250, 307050}, // Single filer {12000 , 46700, 112850, 171950, 307050}, // married filing jointly {6000, 23350, 56425, 85975, 153525}, // married filing separately {10000, 37450, 96700, 156600, 307050} // head of household }; double[] ratesFor2002 = {0.1, 0.15, 0.27, 0.30, 0.35, 0.386}; Tax taxFor2001 = new Tax(0, bracketsFor2001, ratesFor2001, 50000); System.out.println("2001 Tax Table"); System.out.println("taxable\tSingle\tMarried\tMarried\tHead of"); System.out.println("Income\tSingle\tJoint\tSeparate\ta House"); for (int taxableIncome = 50000; taxableIncome <= 60000; taxableIncome += 1000) { taxFor2001.setTaxableIncome(taxableIncome); taxFor2001.setFilingStatus(0); int taxForStatus0 = (int)taxFor2001.findTax(); taxFor2001.setFilingStatus(1); int taxForStatus1 = (int)taxFor2001.findTax(); taxFor2001.setFilingStatus(2); int taxForStatus2 = (int)taxFor2001.findTax(); taxFor2001.setFilingStatus(3); int taxForStatus3 = (int)taxFor2001.findTax(); System.out.println(taxableIncome + "\t" + taxForStatus0 + "\t" + taxForStatus1 + "\t" + taxForStatus2 + "\t" + taxForStatus3); } Tax taxFor2002 = new Tax(0, bracketsFor2002, ratesFor2002, 50000); System.out.println("2002 Tax Table"); System.out.println("taxable\tSingle\tMarried\tMarried\tHead of"); System.out.println("Income\tSingle\tJoint\tSeparate\ta House"); for (int taxableIncome = 50000; taxableIncome <= 60000; taxableIncome += 1000) { taxFor2002.setTaxableIncome(taxableIncome); taxFor2002.setFilingStatus(0); int taxForStatus0 = (int)taxFor2002.findTax(); taxFor2002.setFilingStatus(1); int taxForStatus1 = (int)taxFor2002.findTax(); taxFor2002.setFilingStatus(2); int taxForStatus2 = (int)taxFor2002.findTax(); taxFor2002.setFilingStatus(3); int taxForStatus3 = (int)taxFor2002.findTax(); System.out.println(taxableIncome + "\t" + taxForStatus0 + "\t" + taxForStatus1 + "\t" + taxForStatus2 + "\t" + taxForStatus3); } } } class Tax { public final static int SINGLE_FILER = 1; public final static int MARRIED_JOINTLY = 2; public final static int MARRIED_SEPARATELY = 3; public final static int HEAD_OF_HOUSEHOLD = 4; private int filingStatus = SINGLE_FILER; private int[][] brackets = { {27050, 65550, 136750, 297350}, // Single filer {45200, 109250, 166500, 297350}, // married filing jointly {22600, 54625, 83250, 148675}, // married filing separately {36250, 93650, 151650, 297350} // head of household }; private double[] rates = {0.15, 0.275, 0.305, 0.355, 0.391}; private double taxableIncome = 100000; public Tax() { } public Tax(int filingStatus, int[][] brackets, double[] rates, double taxableIncome) { this.filingStatus = filingStatus; this.brackets = brackets; this.rates = rates; this.taxableIncome = taxableIncome; } public void setBrackets(int[][] brackets) { this.brackets = brackets; } public void setRates(double[] rates) { this.rates = rates; } public double getTaxableIncome() { return taxableIncome; } public void setTaxableIncome(double taxableIncome) { this.taxableIncome = taxableIncome; } public int getFilingStatus() { return filingStatus; } public void setFilingStatus(int filingStatus) { this.filingStatus = filingStatus; } public double findTax() { double tax = 0; // Compute tax in the first bracket if (taxableIncome <= brackets[filingStatus][0]) return tax = taxableIncome * rates[0]; else tax = brackets[filingStatus][0] * rates[0]; int i; // Compute tax in the possible 2nd, 3rd, 4th, and 5th brackets for (i = 1; i < brackets[0].length; i++) { if (taxableIncome > brackets[filingStatus][i]) tax += (brackets[filingStatus][i] - brackets[filingStatus][i - 1]) * rates[i]; else { tax += (taxableIncome - brackets[filingStatus][i - 1]) * rates[i]; break; } } // Compute tax in the possible last bracket if (i == brackets[0].length && taxableIncome > brackets[filingStatus][i - 1]) tax += (taxableIncome - brackets[filingStatus][i - 1]) * rates[i]; return tax; } }