Intro to Computer Science I Chapter 4 Classes, Objects, and Methods OOP Concepts 1 Strings (1) BGA A String is a sequence of 0 or more characters Every string has a length associated with it An empty string has length 0 Each character is stored internally as a 16-bit Unicode character (16-bit integer) Each character in a string has an index associated with it. 2 Strings (2) Literal string: sequence of 0 or more characters delimited by double quote characters The double quotes Example: "Hello" are not part of the string Empty string: "" Memory model: index begins at 0 BGA H e l l o 0 1 2 3 4 3 Substring BGA A substring is constructed by specifying a subsequence of characters H e l l o 0 1 2 3 4 e l l 0 1 2 A substring is a string 4 Constructing a literal string Strings are objects String greeting = "Hello World"; greeting String Hello World object reference variable object reference object BGA 5 String expressions BGA Strings can be concatenated together Numeric values can be automatically converted to strings The + sign is used to denote addition and also string concatenation RULE: In a + b if one of a or b is a string then the other will be converted to a string if necessary 6 String expression examples String first = "William"; String middle = "James"; String last = "Duncan"; String fullName = first + " " + middle + " " + last; fullname has the value "William James Duncan" BGA 7 Mixed string expressions (1) String area = "Area: " + Math.sqrt(2.0); The value of area is "Area: 1.4142135623730951" You can try this in BeanShell and use print(area); to see the result BGA 8 Mixed string expressions (2) "The sum of " + x + " and " + y + " is " + x + y if x is 3 and y is 4 then the result of this expression is "The sum of 3 and 4 is 34" What's wrong? BGA 9 Length of a string Prototype: int length() Example: String name = "Harry"; int len = name.length(); The value of len will be 5 BGA 10 Number to string conversion Examples String s1 = "" + age; String s2 = "" + area; If age is 34 and area is 2.34 then s1 and s2 will have the values "34" and "2.34" BGA 11 Extracting characters Prototype: char charAt(int index) Example String s = "Hello"; char c = s.charAt(1); Here the value of c is 'e' (index begins at 0) BGA 12 Substring construction Prototypes String substring(int firstIndex) String substring(int firstIndex, int lastIndexPlusOne) int d = 531452; String sd = "" + d; int len = sd.length(); sd = "$" + sd.substring(0,len-3) + "," + sd.substring(len-3); BGA result is "$531,452" 13 Trimming spaces Prototype String trim() String s = " s = s.trim(); Hello "; result is "Hello" BGA 14 String case conversion upper/lower case conversion Prototypes String toLowerCase() String toUpperCase() String test = "Hello"; String upper = test.toUpperCase(); String lower = test.toLowerCase(); char first = test.toLowerCase().charAt(0); results are "HELLO", "hello" and "h" BGA 15 String search methods Searching for one string inside another signature Prototypes int int int int indexOf(char ch) indexOf(char ch, int startIndex) indexOf(String sub) indexOf(String sub, int startIndex) Method Overloading: these methods all have the same name but they have different signatures BGA 16 String search examples String target = "This is the target string"; target.indexOf('u') target.indexOf("the") target.indexOf("target",13) BGA value is -1 value is 8 value is -1 17 Displaying numbers, strings Some prototypes: void void void void void void void print(int n) print(double d) print(String s) println(int n) println(double d) println(String s) println() print but don't move to next line print and move to next line Output appears in the terminal window BGA 18 Examples: double area = 3.14159; System.out.println("Area: " + area); double area = 3.14159; System.out.print("Area: "); System.out.println(area); These produce the same results BGA 19 Examples: System.out.println("Hello"); System.out.print("Hello\n"); \ is called the escape character These produce the same results since \n is interpreted as the newline character BGA 20 Examples: System.out.println("\"\\Hello\\\""); Displayed result is "\Hello\" BGA 21 The BlueJ terminal window put this method in CircleCalculator class public void display() { System.out.println("Radius = " + radius); System.out.println("Area = " + area); System.out.println("..."); } BGA 22 The toString method Prototype Purpose return a string representation of an object Default representation BGA public String toString() toString is special: every class has a default toString method with a string representation that is not very useful so we normally provide our own version of this method. 23 Default toString example bsh % addClassPath("c:/book-projects/chapter3"); bsh % CircleCalculator circle = new CircleCalculator(3.0); bsh % String rep = "toString gives " + circle; bsh % print(rep); toString gives CircleCalculator@4d1d41 bsh % rep = "toString gives " + circle.toString(); bsh % print(rep); Not very toString gives CircleCalculator@4d1d41 meaningful bsh % print(circle); CircleCalculator@4d1d41 Using the object name circle in a string expression is equvalent to using circle.toString() BGA 24 Define our own toString public String toString() { return "CircleCalculator[radius=" + radius + ", area=" + area + ", circumference=" + "]"; } now the displayed result is meaningful add this method to CircleCalculator cass print(circle); CircleCalculator[radius=3.0, area=28.274333882308138, circumference=18.84955592153876] BGA 25 Why toString ? It is useful to write a toString method for every class. The toString representation of an object obj can be displayed using BGA System.out.println(obj); This is useful for debugging classes (finding logical errors) since it provides an easy way to display the state of any object. 26 Formatting data (Java 5) The String class contains a static method with prototype public static String format(String f, Object... args) Here f is the format string and Object... args represents the argument list of values to be formatted. There is also a new printf method that can be used with a format string that has the prototype public void printf(String f, Object... args) BGA 27 Format codes (Java 5) Format codes begin with % Here are some useful ones (see javadoc for complete list) %5d %-5d %-20s %15.5f %.5f %20.8e BGA format an integer right justified in field of width 5 format at integer left justified in a field of width 5 format s string left justified in a field of width 20 format a floating point number right justified in a field of width 15 using fixed format rounded to 5 digits after the decimal point format a floating point nuber in a field that just fits using fixed format rounded to 5 digits after the decimal point format a floating point number right justified in a field of width 20 using exponential (scientific) format rounded to 8 digits after the decimal point 28 Format example (1) The statements int i = 3; double pi = Math.PI; String end = "End"; String f = String.format("answer: %5d%15.5f%10s\n", i, pi, end); System.out.println(f); produce the output answer: 3 %5d BGA 3.14159 %15.5f End %10s 29 Format example (2) The statements int i = 3; double pi = Math.PI; String end = "End"; System.out.printf("answer: %5d%15.5f%10s\n", I, pi, end); produce the same output using printf answer: 3 %5d 3.14159 %15.5f End %10s To reuse formats use the format method in the String class BGA 30 Format example(3) In the CircleCalculator class we could include the following display method that formats the results. public void display() { System.out.printf("Radius = %.5f\n", radius); System.out.printf("Area = %.5f\n", area); System.out.printf("Circumference = %.5f\n", circumference); } to display the values rounded to 5 digits after the decimal point in fields that just fit. BGA 31 Intro to Computer Science I Chapter 4 Example classes that use the String class 32 Design, Implement, Test Begin with an English description of a class Design the class by deciding what constructors and methods it should have. BGA This is called writing the public specification or public interface. Write the complete class by providing the implementation Test the class by itself using BlueJ 33 BankAccount class description BGA A BankAccount object should represent a bank account using an account number, an owner name, and a current balance. There should be a constructor for creating a bank account given these values. There should be methods to withdraw or deposit a given amount and the usual "get methods" for retrurning the account number, owner name, and balance. 34 BankAccount class design public class BankAccount { // instance data fields go here public BankAccount(int accountNumber, String ownerName, double initialBalance) {...} public void deposit(double amount) {...} public void withdraw(double amount) {...} public int getNumber() {...} public String getOwner() {...} public double getBalance() {...} public String toString() {...} } BGA 35 How will we use the class Construct an object BankAccount account = new BankAccount(123, "Fred", 125.50); withdraw $100 account.withdraw(100); display balance System.out.println("Balance is " + account.getBalance()); BGA 36 formal and actual arguments Actual arguments in constructor call expression BankAccount myAccount = new BankAccount(123, "Fred", 125.50); Formal arguments in constructor prototype public BankAccount(int accountNumber, String ownerName, double initialBalance) { ... } Same idea applies to method call expressions and prototypes BGA 37 Implementing the class (1) instance data fields private int number; private String name; private double balance; BGA 38 Implementing the class (2) constructor implementation public BankAccount(int accountNumber, String ownerName, double initialBalance) { number = accountNumber; name = ownerName; balance = initialBalance; } BGA 39 Implementing the class (3) deposit, withdraw (mutator methods) public void deposit(double amount) { balance = balance + amount; } public void withdraw(double amount) { balance = balance - amount; } BGA 40 Implementing the class (4) get methods (enquiry methods) public int getNumber() { return number; } public String getName() { return name; } public double getBalance() { return balance; } BGA 41 Implementing the class (5) toString method public String toString() { return "BankAccount[" + "number=" + number + ", name=" + name + ", balance=" + balance + "]"; } BGA 42 BankAccount class (1) public class BankAccount { private int number; private String name; private double balance; public BankAccount(int accountNumber, String ownerName, double initialBalance) { number = accountNumber; name = ownerName; balance = initialBalance; } BGA 43 BankAccount class (2) public void deposit(double amount) { balance = balance + amount; } public void withdraw(double amount) { balance = balance – amount; } public int getNumber() { return number; } BGA 44 BankAccount class (3) public String getName() { return name; } public double getBalance() { return balance; } public String toString() { return "BankAccount[number=" + number + ", name=" + name + ", balance=" + balance + "]"; } } BGA 45 BankAccount with BeanShell addClassPath( "c:/book-projects/chapter4/bank-account"); BankAccount account = new BankAccount(123, "Fred", 125.50); account.withdraw(100); print(account.getBalance()); 25.5 account.deposit(100); print(account.getBalance()); 125.5 print(account); BankAccount[number=123, name=Fred, balance=125.5] BGA 46 BankAccount with BlueJ BGA 47 InitialsMaker description BGA An InitialsMaker object uses the first and last name of a person to produce the initials in uppercase. For example, if the name is Henry James or henry james then the initials are HJ. 48 InitialsMaker design public class InitialsMaker { // instance data fields go here public InitialsMaker(String firstName, String lastName) {...} public String getInitials() {...} public String toString() {...} } BGA 49 Implementing the class (1) instance data field private String initials; Another possibility private String firstName; private String lastName; private String initials; BGA 50 Implementing the class (2) Constructor public InitialsMaker(String firstName, String lastName) { initials = firstName.substring(0,1); + lastName.substring(0,1); initials = initials.toUpperCase(); } BGA 51 Implementing the class (3) get method public String getInitials() { return initials; } toString method public String toString() { return "InitialsMaker[initials=" + initials + "]"; } BGA 52 InitialsMaker with BeanShell addClassPath( "c:/book-projects/chapter4/strings"); InitialsMaker maker = new InitialsMaker("harry", "James"); print(maker.getInitials()); HJ print(maker); InitialsMaker[initials=HJ] Test all four possibilities for the names: "Henry James", "Henry james", "henry James'", "henry james" BGA 53 PasswordGenerator description BGA A PasswordGenerator object generates random 7 character passwords. The first four characters should be lower case letters and the last three characters should be digits 0 to 9. 54 Random number generation In the Math class there is the random() method that returns a real number 0 r 1 In the java.util package there is a Random class that does what we want. generated Constructors and methods sequence depends on current time in milliseconds public Random() public Random(long seed) public int nextInt() repeatable by using 0 i n 1 BGA the same seed again 55 Random digits and characters nextInt(10) generates random integer 0,1,...,9 which can be converted to a character nextInt(26) generates random integer 0,1, ...,25 which can be used as an index into the string index 0 "abcdefghijklmnopqrstuvwxyz" to generate a random letter BGA index 25 56 PasswordGenerator design public class PasswordGenerator { // instance data fields go here public PasswordGenerator() {...} public PasswordGenerator(long seed) {...} public String next() {...} } Each call to next produces a random password BGA 57 Using the class First construct PasswordGenerator object Each call to next returns a random password BGA PasswordGenerator gen = new PasswordGenerator(); String p1 = gen.next(); String p2 = gen.next(); String p3 = gen.next(); 58 Implementation (1) data fields static class data feld (not associated with any object) private static final String LETTERS = "abcdefghijklmnopqrstuvwxyz"; private Random random; Instance data feld BGA 59 Implementation (2) Constructors public PasswordGenerator() { random = new Random(); } public PasswordGenerator(long seed) { random = new Random(seed); } BGA 60 Implementation (3) The next method public String next() { int index; String password = ""; index = random.nextInt(26); password = password + LETTERS.substring(index, index + 1); // repeat these two statements three more times index = random.nextInt(10); password = password + index; // repeat these two statements two more times return password; } BGA 61 Import statement (1) The Random class is not in the standard java.lang package that is automatically imported into every java class It is in java.util and needs to be imported excplicity using import java.util.Random; This statement goes OUTSIDE the class declaration at the top of the file BGA 62 Import statement (2) Another variation is import java.util.*; This can import and class in the java.util package If the import statement is not used then it is necesary to use the fully qualified name java.util.Random of the Random class instead of the short name BGA 63 Testing the class addClassPath("c:/book-projects/chapter4/strings"); PasswordGenerator gen = new PasswordGenerator(); print(gen.next()); avfi637 print(gen.next()); iqde665 gen = new PasswordGenerator(); // make a new one print(gen.next()); zuwe456 gen = new PasswordGenerator(123); print(gen.next()); eomt574 gen = new PasswordGenerator(123); print(gen.next()); eomt574 BGA 64 Test with BlueJ Construct an object Use the next method repeatedly from the object menu Can also insert the simple method public test() { System.out.println(next()); } this.next() BGA 65 The "this" object When you write a class and call a method from the same class what is the object on which the method is invoked? Method call expression with an Compare gen.next(); this.next(); next(); explict object called gen Method call expression from within the PasswordGenerator class If object name is omitted for an instance method the compiler assumes that the method is in the same class BGA 66 Association & Aggregation (1) Programs normally consist of interacting objects from several classes. Types of classes BGA built-in classes such as String or Random classes obtained from someone else classes you write yourself such as CircleCalculator The terms association and aggregation are used to describe how classes can relate to each other. 67 Association (1) Some classes such as CircleCalculator from Chapter 3 are not related with any other classes. Others depend on other classes Example BGA PasswordGenerator uses (depends on) the String and Random classes This dependence of one class on others is called association 68 Association (2) BGA The PasswordGenerator class is associated with, or uses, or depends on the String and Random classes. The relationship is not symmetric For example, we don't say that the String class is associated with the PasswordGenerator class The String class is designed to be used by other classes 69 Association (3) Class A is associated with class B if A uses B. This can occur in several ways. BGA An object of B is used as a local variable in a constructor or method in A An object of B is used as a method or constructor argument in A An object of B is used as a return value of a method in A An object of B is an instance data field in A 70 Aggregation Aggregation (sometimes called composition) refers to the important last case that an object of B is used as an instance data field of A. This is gives rise to an object hierarchy Example BGA Random class is used as instance data fields in PasswordGenerator 71 TriangleCalculatorTester public class TriangleCalculatorTester { public TriangleCalculatorTester() Can omit constructor { } public void doTest(double a, double b, double g) { TriangleCalculator tri = Association new TriangleCalculator(a,b,g); System.out.println("Sides: " + tri.getA() + ", " + tri.getB() + ", " + tri.getC()); System.out.println("Angles: " + tri.getAlpha() + ", " + tri.getBeta() + ", " + tri.getGamma()); System.out.println("Angle sum is " + tri.checkAngleSum()); } In BlueJ a dotted arrrow indicates association } BGA 72 Association in BlueJ the dotted arrow indicates association TriangleCalculatorTester is associated with (uses) TriangleCalculator BGA doTest produces this output 73 Point class design public class Point { private double x, y; public Point() {...} public Point(double x, double y){...} public double getX() {...} public double getY() {...} public String toString() {...} } BGA 74 Point class implementation (2) public class Point { private double x, y; public Point() { x = y = 0.0; } public Point(double x, double y) { this.x = x; this.y = y; } BGA 75 Point class implementation (2) public double getX() { return x; } public double getY() { return y; } public String toString() { return "Point[" + x + ", " + y +"]"; } } // end of class BGA 76 Testing the Point class addClassPath("c:/book-projects/chapter4/geometry"); import Point; // necessary or we get java.awt.Point Point origin = new Point(0,0); Point p = new Point(1,2); print(origin); Point[0.0, 0.0] print(p); Point[1.0, 2.0] print(p.getX()); 1.0 print(p.getY()); 2.0 BGA 77 Designing a circle class We want to develop a simple Circle class to describe geometric circles in terms of their center (x,y) and radius r Method 1 Method 2 (using aggregation) BGA Use three double type instance data fields for the center coordinates and the radius Use two instance data fields. One is a Point object for the center and the other is the radius 78 Circle class design (method 1) public class Circle { private double x, y, radius; public Circle() {...} public Circle(double x, double y, double r) {...} public double getX() {...} public double getY() {...} public double getRadius() {...} public String toString() {...} } BGA 79 Circle class design (method 2) public class Circle { private Point center; private double radius; aggregation public Circle() {...} public Circle(double x, double y, double r) {...} public Circle(Point c, double r) {...} public Point getCenter() {...} public double getRadius() {...} public String toString() {...} } BGA 80 Implementation (1) Constructors public Circle(Point p, double r) { center = p; radius = r; } public Circle(double x, double y, double r) { center = new Point(x,y); radius = r; } public Circle() { center = new Point(); radius = 1; } BGA 81 Implementation (2) Methods public double getRadius() { return radius; } public Point getCenter() { return center; } public String toString() { return "Circle[" + center + ", " + radius + "]"; } BGA 82 Testing the class (BeanShell) addClassPath("c:/book-projects/chapter4/geometry"); import Point; Point center = new Point(3,4); Circle c1 = new Circle(); Circle c2 = new Circle(center, 5); Circle c3 = new Circle(3,4,5); print(c1); multiple method Circle[Point[0.0, 0.0], 1.0] call expressions print(c2); Circle[Point[3.0, 4.0], 5.0] print(c3); Circle[Point[3.0, 4.0], 5.0] double x = c2.getCenter().getX(); print(x); 3.0 BGA 83 Testing the class (BlueJ) Point object for (3,4) BGA use it here as constructor argument 84 CircleTester (1) public class CircleTester { public CircleTester() { } can omit constructor Construct 3 circle objects public void doTest() { Point center = new Point(3,4); Circle c1 = new Circle(); Circle c2 = new Circle(center, 5); Circle c3 = new Circle(3,4,5); BGA 85 CircleTester (2) System.out.println("c1 = " + c1); System.out.println("c2 = " + c2); System.out.println("c3 = " + c3); double radius = c2.getRadius(); double x = c2.getCenter().getX(); double y = c2.getCenter().getY(); display using toString aggregation System.out.println("Radius = " + radius); System.out.println("Center x = " + x); System.out.println("Center y = " + y); } // end of doTest method } // end of CircleTester class BGA 86 Other Library classes Dates and times Calendars Currency formatting numeric formatting 87 Date class Represents dates as the number of milliseconds since January 1, 1970, 00:00:00 GMT as a long value Example 1055681816162 = Sun Jun 15 08:56:57 EDT 2003 toString provides this BGA 88 Date class specification Some of the constructors and methods are public Date() date right now public Date(long date) public long getTime() public void setTime(long date) public String toString() Date class is in package java.util BGA 89 Date example (BeanShell) import java.util.Date; We are 5 hours Date now = new Date(); ahead of print(now); midnight GMT Sun Jun 15 08:56:56 EDT 2003 long t = now.getTime(); print(t); 1055681816162 Date first = new Date(0L); print(first); Wed Dec 31 19:00:00 EST 1969 first.setTime(0L + 1000L * 60L * 60L * 24L); print(first); Thu Jan 01 19:00:00 EST 1970 milliseconds in a day BGA 90 SimpleDateFormat class We need to be able to display dates in various formats. This class is in SimpleDateFormat can do this package Constructors and methods java.text public SimpleDateFormat() public SimpleDateFormat(String pattern) public String format(Date d); Convert a Date object to the format specified by the constructor BGA 91 Example (BeanShell) import java.util.Date; import java.text.SimpleDateFormat; Date now = new Date(); SimpleDateFormat f1 = new SimpleDateFormat(); String n1 = f1.format(now); print(n1); 6/15/03 8:56 AM SimpleDateFormat f2 = new SimpleDateFormat("dd/MM/yyyy"); print(f2.format(now)); 15/06/2003 SimpleDateFormat f3 = new SimpleDateFormat("HH:mm:ss z"); print(f3.format(now)); 08:56:56 EDT BGA 92 Calendar class BGA A higher level class than Date that knows about year, month, day of month, day of year, etc. Java can use any of the world's calendars depending on the locale. For us this is the Gregorian calendar 93 Constructing a Calendar A constructor is not used to create a Calendar object. Instead a static class methodis used. Method prototype is public static Calendar getInstance() Recall that a static method in a class is not associated with any objects of the class. The Math class methods were like this. Compare Math.sqrt with Calendar.getInstance Calendar now = Calendar.getInstance(); For a static (class) method the class name is used instead of an object name BGA This is a static method call expression 94 Instance versus static method Instance method call expression objectName.methodName(actualArgumentList) Static method call expression ClassName.methodName(actualArgumentList) BGA 95 Some Calendar methods public Date getTime() public int get(int field) public void set(int field, int value) public void set(int year, int month, int day) Calendar fields are integer constants such as Calendar.YEAR, Calendar.MONTH, Calendar.DAY_OF_MONTH BGA 96 Using Calendar class (1) import java.util.Date; factory import java.util.Calendar; method Calendar now = Calendar.getInstance(); Date time = now.getTime(); print(time); Sun Jun 15 10:04:12 EDT 2003 print(now.get(Calendar.YEAR)); 2003 print(now.get(Calendar.MONTH)); // Jan is month 0 5 print(now.get(Calendar.DAY_OF_MONTH)); 15 print(now.get(Calendar.DAY_OF_WEEK)); // Sunday is 1 1 BGA 97 Using Calendar class (2) print(now.get(Calendar.DAY_OF_YEAR)); 166 Calendar christmas = Calendar.getInstance(); int year = christmas.get(Calendar.YEAR); christmas.set(year, Calendar.DECEMBER, 25); print(christmas.getTime()); Thu Dec 25 11:13:01 EST 2003 BGA 98 Leap years import java.util.Calendar; Calendar feb2003 = Calendar.getInstance(); feb2003.set(2003, Calendar.FEBRUARY, 1)); Calendar feb2004 = Calendar.getInstance(); feb2004.set(2004, Calendar.FEBRUARY, 1)); print(feb2003.getActualMaximum( Calendar.DAY_OF_MONTH)); 28 print(feb2004.getActualMaximum( Calendar.DAY_OF_MONTH)); 29 BGA 99 Person class (1) import java.util.Calendar; public class Person { private String name; private int birthYear; public Person(String name, int birthYear) { this.name = name; this.birthYear = birthYear; } BGA 100 Person class (2) public String getName() { return name; } public int getBirthYear() { return birthYear; } Using a Calendar object to determine the person's age public int age() { Calendar now = Calendar.getInstance(); return now.get(Calendar.YEAR) - birthYear; } } // end of class BGA 101 CalendarMonth class (1) BGA Suppose we want to display a calendar for a given year and month. We don't need the full complexity of the Calendar class We can write a simpler version called CalendarMonth called an adapter class An adpater class is a class which makes another class easier to use in specific problems 102 CalendarMonth class (2) We need the following functionality BGA only the year and month parts of a Date are required We need the day of the week for the first day of the month We need to know the number of days in the month properly accounting for leap years in February We need the names of the months so that we can print headings. This class is called an adapter class since it provides a simpler more specialized version of a more complicated class. 103 Class design (specification) public class CalendarMonth calendar for this month { public CalendarMonth() {...} public CalendarMonth(int year, int month) {...} public int getYear() {...} for first day public int getMonth() {...} of month public int dayOfWeek() {...} (1 to 7) public int daysInMonth() {...} public String monthName() {...} public String toString() {...} } BGA 104 Class implementation (1) import java.util.Calendar; import java.util.SimpleDateFormat public class CalendarMonth adapt this class { private Calendar calendar; Constants for month and day names public static final int JANUARY = Calendar.JANUARY; ... public static final int SATURDAY = Calendar.SATURDAY. BGA 105 Class implementation (2) public CalendarMonth() { calendar = Calendar.getInstance(); calendar.set(Calendar.DAY_OF_MONTH, 1); set calendar to } first day of month public CalendarMonth(int year, int month) { calendar = Calendar.getInstance(); calendar.set(year, month, 1); } BGA 106 Class implementation (3) public int getYear() { return calendar.get(Calendar.YEAR); } public int getMonth() { return calendar.get(Calendar.MONTH); } BGA 107 Class implementation (4) public int dayOfWeek() { return calendar.get( Calendar.DAY_OF_WEEK); } 1 = Sunday calendar is already set to first day of month public int daysInMonth() { return calendar.getActualMaximim( Calendar.DAY_OF_MONTH); } BGA 108 Class implementation (5) public String monthName() { SimpleDateFormat f = new SimpleDateFormat("MMMM"); return f.format(calendar.getTime()); } public String toString() { SimpleDateFormat f = new SimpleDateFormat("MMMM yyyy"); return f.format(calendar.getTime()); } } // end of class BGA 109 Using CalendarMonth class (1) addClassPath("c:/book-projects/chapter4/calendar"); CalendarMonth thisMonth = new CalendarMonth(); print(thisMonth.dayOfWeek()); 2 Monday print(thisMonth.daysInMonth()); 30 print(thisMonth.monthName()); September print(thisMonth); September 2003 BGA 110 Using CalendarMonth class (2) // continued from previous slide our constants CalendarMonth feb2004 = new CalendarMonth(2004, CalendarMonth.FEBRUARY); print(feb2004.dayOfWeek()); 1 Sunday print(feb2004.daysInMonth()); 29 leap year print(feb2004.monthName()); February print(feb2004); February 2004 BGA 111 CalendarMonthTester (1) public class CalendarMonthTester { public CalendarMonthTester() {} public void doTest() { CalendarMonth thisMonth = new CalendarMonth(); System.out.println("First day of month is " + thisMonth.dayOfWeek()); System.out.println("Number of days in month is " + thisMonth.daysInMonth()); System.out.println("Month name is " + thisMonth.monthName()); System.out.println("Calendar name is " + thisMonth); BGA 112 CalendarMonthTester (2) System.out.println(); CalendarMonth feb2004 = new CalendarMonth(2004, CalendarMonth.FEBRUARY); System.out.println("First day of month is " + thisMonth.dayOfWeek()); System.out.println("Number of days in month is " + thisMonth.daysInMonth()); System.out.println("Month name is " + thisMonth.monthName()); System.out.println("Calendar name is " + thisMonth); } // end of doTest } // end of class BGA 113 CalendarMonth in Bluej BGA 114 Currency formatting Depends on locale English: $100,000.56 French: 100000,56 $ NumberFormat is in java.text package Construct a NumberFormat object NumberFormat currency = NumberFormat.getCurrencyInstance(); Format it as a string double salary = 4000.56 String value = currency.format(salary); BGA 115 BeanShell example import java.text.NumberFormat; double salary = 100000.555; NumberFormat currency = NumberFormat.getCurrencyInstance(); print(currency.format(salary)); $100,000.56 NumberFormat currencyCF = NumberFormat.getCurrencyInstance( Locale.CANADA_FRENCH); print(currencyCF.format(salary)); 100000,56 $ BGA 116 Formatting fixed numbers Formatting numbers with a fixed number of digits after decimal point import java.text.DecimalFormat; DecimalFormat fix = new DecimalFormat(" 0.00000;-0.00000); print(fix.format(Math.PI)); 3.14159 print(fix.format(-Math.PI)); -3.14159 BGA format for negative numbers format for positive numbers 117 Formatting scientific numbers Formatting numbers with a an exponent and five digits after decimal point import java.text.DecimalFormat; DecimalFormat fix = new DecimalFormat(" 0.00000E000;-0.00000E000); double d = 1.2345678E-23; print(sci.format(d)); format for 1.23457E-023 negative numbers print(fix.format(d)); -1.23457E-023 format for positive numbers BGA 118 Review of OOP concepts constructing objects object references using references data encapsulation and integrity instance variables and methods static variables,constants,methods 119 Constructing objects Objects are constructed in two ways Using a constructor or using a static factory method which returns an object of the class using a static method call expression BGA Circle c1 = new Circle(3,4,5); Calendar now = Calendar.getInstance(); 120 Constructor Examples Constructor call expressions (underlined) Circle c1 = new Circle(new Point(3,4), 5); Point p = new Point(3,4); Point q = new Point(); Circle c1 = new Circle(3, 4, 5); BankAccount a = new BankAccount(123, "Fred", 4000); SimpleDateFormat f = new SimpleDateFormat("MMMM yyyy"); Constructor prototypes public Circle(Point p, double radius) public Point(double x, double y) public Circle(double x, double y, double radius) public BankAccount(int number, String name, double balance) public SimpleDateFormat(String pattern) BGA 121 Static Factory Examples Static method call expressions (underlined) Calendar now = Calendar.getInstance(); NumberFormat currency = NumberFormat.getCurrencyInstance(); Static method prototypes public static Calendar getInstance() public static NumberFormat getCurrencyInstance() BGA 122 Using this as a constructor call public Circle() { center = new Point(); radius = 1; } this(new Point(),1); public Circle(double x, double y double r) { center = new Point(x,y); this(new Point(x,y),r); radius = r; } public Circle(Point p, double r) { center = p; radius = r; } WARNING BGA "this" will call this constructor 123 The Default constructor If you don't put any constructors in a class the default no-arg constructor public ClassName() { } BGA is automatically provided by the compiler. For example in CircleTester we could have omitted the no-arg constructor that was included in the class. 124 Miranda convention BGA You have a right to a constructor. If you do not have one, a default one will be provided to you by the compiler. 125 What does it do? The default constructor simply supplies default initialization for any uninitialized instance data fields: BGA A value of zero is assigned to all uniinitialized numeric data fields. A reference value of null is assigned to all uninitialized data fields of object type (explained later) Try it: see page 142 of text book 126 Object references Constructing an object is a three step process BGA Memory space is allocated for the object and its instance data fields. A reference (address) to the object is returned so that it can be located This reference is assigned as the value of an object reference variable This variable is the object reference variable 127 Pictorial representation objectName ClassName ClassName objectName = new ClassName(actualArguments) objectName Object Data null ClassName objectName; ClassName objectName = null; BGA 128 Circle Example BGA Circle c; Uninitialized reference Circle c = null; null reference Circle c = new Circle(3,4,5); Initialized Reference 129 Primitive and reference types Primitive types numeric types such as int, long, float, double area 17.902 Reference types object types such as String, Circle, BankAccount greeting String Hello World BGA 130 Why do we need both types? BGA Types such as int and double are primitive types for efficiency reasons. There is a certain amount of overhead in following a reference to find an object. There are wrapper classes that let us convert the primitive types to object types Example: Integer class encapsulates an int value 131 Assignment for reference types BGA Primitive types: the assignment statement a = b; means to assign the value of b as the value of a. Reference types: the assignment statement a = b; means to assign the reference b as the value of the reference a and this means that a and b now both reference the same object assignment does not copy objects. 132 a=b for primitive types a 17 a 19 b 19 b 19 Before a = b BGA After a = b 133 a=b for reference types a object A a object A b object B b object B Before a = b BGA After a = b 134 BankAccount example BankAccount fred = new BankAccount(123, "Fred", 150.0); BankAccount mary = new BankAccount(345, "Mary", 250.0); mary = fred; // both reference fred mary.withdraw(100.0); print(mary); BankAccount[number=123, name=Fred, 50.0] print(fred); BankAccount[number=123, name=Fred, 50.0] BGA 135 Where are references used? Local variables in the constructor or method Constructor or method arguments Example: return center; instance data fields (aggregation) BGA Example: public Circle(Point p, double r) method return values Example: TriangleCalculator tri = new TriangleCalculator(a,b,g); Example: private Calendar calendar; 136 Data encapsulation (1) BGA In OOP the data is spread out over the instance data fields of one or more objects Each object is only responsible for its own data This data is normally private so that it cannot be directly changed outside the class This is called data encapsulation. 137 Data encapsulation (2) BGA Classes can be mutable or immutable For mutable classes the constructors and methods that change the values of one or more instance data fields can be written to check that objects are not in an inconsistent state. Example: See page 146 for discussion of public data fields and set methods. 138 Side effects BGA Changing the state of an object indirectly from outside the class Sometimes this is desirable Sometimes side-effects are undesirable Side-effects are normally created by returning references from methods that can be used outside the class to change the state of an object. 139 The MPoint class Our Point class is immutable: it is not possible to change the state of a Point object after it has been constructed Consider a mutable version called MPoint like Point but with following set methods public void { this.x = } public void { this.y = } BGA setX(double x) x; setY(double y) y; 140 The MCircle class Identical to Circle except that it uses aggregation with the mutable MPoint class instead of the immutable Point class The following constructor has side-effects public MCircle(MPoint p, double r) { center can be changed center = p; through p radius = r; } BGA 141 Example of side-effect (1) addClassPath("c:/book-projects/chapter4/side-effects"); MPoint p = new MPoint(3,4); MCircle c = new MCircle(p, 5); Also try it print(c); in BlueJ MCircle[MPoint[3.0, 4.0], 5.0] p.setX(999); print(c); MCircle[MPoint[999.0, 4.0], 5.0] The change in the x coordinate of point p outside the MCircle class has the side-effect of changing the x coordinate of the center of the circle. This is normally an undesirable side-effect since it violates the data encapsulation. BGA 142 Example of side-effect (2) addClassPath("c:/book-projects/chapter4/side-effects"); MCircle c = new MCircle(3, 4, 5); print(c); MCircle[MPoint[3.0, 4.0], 5.0] reference to MPoint p = c.getCenter(); center is returned p.setX(999); print(c); MCircle[MPoint[999.0, 4.0], 5.0] Also try it in BlueJ BGA 143 Example of side-effect (3) The problems occurs with the assignment statement center = p; and with the statement return center; BGA This gives two references to the same point object. One reference inside the class (center) and one outside the class (p). 144 Example of side-effect (4) MPoint p c x 999 y 4 MCircle center radius 5 There are two references to one MPoint object BGA 145 No side-effect in original classes addClassPath("c:/book-projects/chapter4/geometry"); import Point; Point p = new Point(3,4); Circle c = new Circle(p, 5); print(c); Circle[Point[3.0, 4.0], 5.0] MPoint p = c.getCenter(); p = new Point(999,4); print(c); Circle[Point[3.0, 4.0], 5.0] BGA 146 Fixing the side-effect (1) Include a copy constructor in MPoint class public MPoint(MPoint p) { x = p.x; y = p.y; } General form of copy constructor public ClassName ( ClassName objectName ) BGA 147 Fixing the side-effect (1) Revise the constructor that takes an MPoint object as an argument public MCircle(MPoint p, double r) { center = new MPoint(p); radius = r; } Revise getCenter method public MPoint getCenter() { return new MPoint(center); } BGA Now center references its own private copy of the MPoint object Now we return a copy of the private MPoint object 148 Side-effects are gone addClassPath( "c:/book-projects/chapter4/no-side-effects"); MPoint p = new MPoint(3,4); MCircle c = new MCircle(p, 5); print(c); This has no MCircle[MPoint[3.0, 4.0], 5.0] effect on p.setX(999); MCircle print(c); MCircle[MPoint[3.0, 4.0], 5.0] BGA 149 Pictorial Representation MPoint p c MPoint x 999 x 3 y 4 y 4 MCircle center Now p and c are references to different objects BGA radius 5 150 BankAccount transfer (1) public class TransferAgent { public TransferAgent(BankAccount from, BankAccount to) {...} public void transfer(double amount) {...} } The constructor takes references to the two BankAccount objects that participate in the transfer. The transfer method does the transfer of a given amount from one account to the other BGA 151 BankAccount transfer (2) public class TransferAgent { private BankAccount from; private BankAccount to; Aggregation public TransferAgent(BankAccount from, BankAccount to) { this.from = from; this.to = to; } public void transfer(double amount) { from.withdraw(amount); to.deposit(amount); } } BGA bank-account project 152 Side-effects (1) BGA The BankAccount class is mutable and there will be side-effects in the TransferAgent class The side-effects are desired here since the purpose of the transfer method is to change the balances in the two accounts referenced by from and to suplied by the user. 153 Side-effects (2) addClassPath("c:/book-projects/chapter4/bank-account"); BankAccount fred = new BankAccount(123,"Fred",1000); BankAccount mary = new BankAccount(345,"Mary",1000); TransferAgent agent = new TransferAgent(fred, mary); agent.transfer(500); print(fred); BankAccount[number=123, name=Fred, balance=500] print(mary); try it in BankAccount[number=345, name=Mary, balance=1500] BlueJ BGA 154 Instance variables BGA Instance variables are also called instance data fields They are declared in the class but outside any method or constructor Only instance methods have access to these variables Each object has its own set of instance variables 155 Instance methods BGA Instance methods are associated with objects of the class Instance methods can access the instance data fields 156 Using an instance method BGA To use or call an instance method means to invoke it on some object using an instance method call expression We also say that instance methods are used to send messages to objects. 157 Examples int length = name.length(); char first = test.toUpperCase.charAt(0); password = password + LETTERS.substring(index,index+1); String upper = test.toUpperCase(); account.deposit(100)); message composition String firstInitial = firstName.substring(0,1).toUpperCase(); double x = c2.getCenter().getX(); doCalculations(); // this is the implied object long t = now.getTime(); String n3 = f3.format(now); Method call expressions are underlined in red BGA objectName.methodName(actualArguments) this.methodName(actualArguments) 158 prototypes and call expressions String letter = LETTERS.substring(index, index + 1); public String substring(int first, int lastPlusOne) BGA 159 Method composition Also called message composition objectName.methodName(args1) . methodName(args2) ... methodName(argsN) this.methodName(args1) . methodName(args2) ... methodName(argsN) BGA 160 Static variables (1) Also called class variables Declared using the static modifier inside a class but outside any method or constructor declaration. We have not used them yet Example BGA private static int count = 0; 161 Static variables (2) They are not associated with any objects. They belong to the class. Each static variable is shared by all the objects of the class (shared variable) This is very different from instance variables 1 2 count BGA 3 4 0 162 Static constants Constants are declared to be static since there is no need to have separate copies of a constant, one for each object. Examples public static final String LETTERS = "abcdefghijklmnopqrstuvwxyz"; public static final int JANAURY = Calendar.JANUARY; BGA 163 Static methods (1) They are methods that are not associated with any objects of a class. To use them in another class prefix the name of the method with the class name beta = Math.toDegrees(beta); System.out.println("Area: " + area); Calendar now = Calendar.getInstance(); NumberFormat currency = NumberFormat.getCurrencyInstance(); Static method call expressions are underlined in red BGA 164 Static Methods (2) General syntax instance method call expressions (1) objectName.methodName(actualArguments) (2) this.methodName(actualArguments) General syntax for static method call expressions (1) className.methodName(actualArguments) (2) methodName(actualArguments) BGA 165 Counting objects (1) We can illustrate static variables (shared varibles) and static methods by writing a version of the Point class that keeps track of the number of Point objects that have been counted so far. Add following static data field to the Point class public static int count = 0; BGA 166 Counting objects (2) Add the following statement to the body of each different constructor (but not if "this" is used) count++; Add the following static method to the class public static int getCount() { return count; } BGA 167 Testing Point (BeanShell) addClassPath( "c:/book-projects/chapter4/static-variable"); import Point; Point p1 = new Point(1,2); Point p2 = new Point(3,4); this does not Point p3 = new Point(4.5); create a new object Point p4 = p1; int objectCount = Point.getCount(); print(objectName); 3 Also try it with BlueJ Note that static methods appear on the Constructor menu not the object menu. BGA 168 Classifying variables and args Instance data fields Static (class) data fields declared in the body a constructor or method and are only accessible there Formal arguments BGA static variables not associated with objects Local variables instance variables associated with objects declared in method or constructor prototype and are local variables 169 Call by value Argument passing mechanism is always call by value in Java: BGA if an actual argument is a variable then a copy of its value is supplied as the value of the formal argument. If an actual argument is a literal (literal string or number for example) then this value is supplied as the value of the formal argument If an actual argument is an expression then it is evaluated and its value is supplied as the value of the formal argument. 170 Call by value (primitive type) BGA If a constructor or method argument is a primitive type and a variable is used as an actual argument, then the value of the variable can never be changed by the method or constructor since only a copy of the variable's value, not its location, is passed to the method. 171 Example (BeanShell) void addOne(int k) { k = k + 1; } int m = 5; addOne(m); static methods can print(m); be defined directly 5 in BeanShell print(k); // Error: indefined variable The value of m is not changed by the addOne method since only the value 5 is passed to the method so the method simply adds 1 to the local variable k which disappears anyway when the method exits. BGA 172 Example (BlueJ) Write the following simple class public class ArgumentTester1 { public void doTest() { int m = 5; addOne(m); System.out.println(m); } private static void addOne(int k) { k = k + 1; } } BGA arguments project in Chapter 4 173 Call by value (reference type) BGA For reference type (object type) the situation is quite different We still use "call by value" but now the value passed is a copy of a reference to the caller's object so there will now be two references to the caller's object In the case of mutable classes this means that the caller's object can be changed (sideeffect). 174 Example (BeanShell) addClassPath("c:/book-projects/chapter4/arguments"); void addOne(BankAccount b) { b.deposit(1) } BankAccount a = new BankAccount(123,"Fred",1000); addOneDollar(a); print(a); BankAccount[number=123, name=Fred, balance=1001.0] The value of a is not changed by the addOneDollar method but since a is a reference to a BankAccount then the deposit statement does change the balance of the caller's account as referenced by a BGA 175 Example (BlueJ) Write the following simple class public class ArgumentTester2 { public void doTest() { BankAccount a = new BankAccount(123, "Fred", 1000); addOneDollar(a); System.out.println(a); } } BGA private static void addOneDollar(BankAccount b) { b.deposit(1); } arguments project in Chapter 4 176 Pictorial Representation a BankAccount balance Before method call 1000 a b a BankAccount balance 1001 BankAccount balance BGA Reference b is local to method so it has disappeared During method call 1001 After method call 177 The main method (1) BGA Executing a class outside the BlueJ environment The JRE (java run time environment) has an interpreter that can be run from the command line using a command prompt For this to work the class must have a special static method called the main method 178 Main method (2) Form of the main method must be public static void main(String[] args) { ... } The java interpreter will begin executing your program at the first statement in the main method. This method is normally used only to create an object of the class that starts your program BGA We won't use this argument until Chapter 8 but it must be there 179 Adding a main method Add a main method to the CircleTester class public class CircleTester { ... public void doTest() { ... } } BGA main will construct a CircleTester object and run the test public static void main(String[] args) { CircleTester tester = new CircleTester(); tester.doTest(); } see main-method project Can also execute main method from inside BlueJ 180 Another approach BGA If you don't want to add a main method to the class you want to run you can write a special class that only has a main method This main method can construct an object of the other class and execute its methods. 181 BankAccountRunner public class BankAccountRunner { public void doTest() { BankAccount account = new BankAccount(123, "Fred", 125.50); System.out.println("Initial balance is " + account.getBalance(); account.withdraw(100); System.out.println("Balance is " + account.getBalance(); ... } uses default constructor public static void main(String[] args) { BankAccountRunner runner = new BankAccountRunner(); runner.doTest(); } } BGA 182 Run from command line cd to the directory containing the BankAccountRunner class Compile the class (if you haven't used BlueJ to do it) javac BankAccountRunner.java Now run the class using its main method BGA c:\book-projects\chapter4\main-method java BankAccountRunner 183 BankAccountRunner output java BankAccountRunner interpreter command Initial balance is 125.5 Balance is 25.5 Balance is 125.5 BankAccount[number=123, name=Fred, balance=125.5] output produced by System.out.println statements BGA 184