Classes Chapter 4 Fall 2006 CS 101 Aaron Bloomfield 1 Preparation Scene so far has been background material and experience Computing systems and problem solving Variables Types Input and output Expressions Assignments Using objects Standard classes and methods Decisions (if, switch) Loops (while, for, do-while) Next: Experience what Java is really about Design and implement objects representing information 2 and physical world objects Object-oriented programming Basis Create and manipulate objects with attributes behaviors that the programmer can specify and Mechanism Classes Benefits An information type is design and implemented once Reused as needed No need reanalysis and re-justification of the representation 3 Known Classes Classes we’ve seen BigInteger String Rectangle Vector Scanner System Classes we’ll be seeing soon BigDecimal But the first step is on creating methods… 4 Methods 5 Methods we’ve seen We’ve seen methods (functions) before angleSin = Math.sin (90 * PI/180.0); System.out.println (“Hello world”); value = card.getBlackjackValue(); We are going to start defining them Note that many of these “return” a value Math.sin() and card.getBlackjack() The way to name methods is the same as variables allTheWordsTogether With the first letter of each word capitalized Except the very first letter is lower case 6 Our first class with methods public class Methods1 { public static void main (String args[]) { Scanner stdin = new Scanner (System.in); System.out.println ("Enter a valid int value"); int value = stdin.nextInt(); if ( value == 1 ) validValue(); else if ( value == 2 ) validValue(); else if ( value == 3 ) invalidValue(); else if ( value == 4 ) invalidValue(); else validValue(); } 7 } Our first class with methods, continued public static void invalidValue() { System.out.println ("You have entered an invalid value."); System.out.println ("The program will now exit."); System.exit (0); } public static void validValue() { System.out.println ("You have entered an valid value."); System.out.println ("Congratulations!"); System.out.println ("The program will now exit."); System.exit (0); } 8 Program Demo Methods1.java 9 What’s happening there public static void validValue() { System.out.println ("You have entered an valid value."); System.out.println ("Congratulations!"); System.out.println ("The program will now exit."); System.exit (0); } public static void main (String args[]) { Scanner stdin = new Scanner (System.in); System.out.println ("Enter a valid int value"); int value = stdin.nextInt(); if ( value == 1 ) value stdin validValue(); // ... Scanner } 1 10 Notes on these methods At this point, all methods in the class are static We will be discussing what static means later in this slide set Until then, I’ll be ignoring it, and just telling you when things should and should not be static Sorry! None of those two methods return a value Notice the “void” before the method name And none take in any parameters Notice the empty parameters after the method name 11 Today’s demotivators 12 HW J3 13 Revamping HW J3 Start here Done tech support? Cynical guru Bitter yet? Successful managing? Promoted Become a coder A revised HW 3 flowchart Green paths are “yes” paths, red are “no” paths We’ll make a slight modification to the diagram: Note that this part is repeated twice! Been a sysadmin? Worked with NT? Want to play w/nukes? Hate people? Start over Public danger Defense contractor 14 HW J3 Code The yellow boxed part is what was repeated from the previous slide if ( extractor.askUser(Q_TECH_SUPPORT) ){ if ( extractor.askUser(Q_BITTER_YET) ) if ( extractor.askUser(Q_MANAGEMENT) ) System.out.println (A_CYNICAL); else System.out.println (A_PROMOTED); else System.out.println (A_START_OVER); } else if ( extractor.askUser(Q_BEEN_SYSADMIN) ){ if ( extractor.askUser(Q_HATE_PEOPLE) ) { System.out.println (A_CODER); } else if ( extractor.askUser(Q_WINNT) ){ if ( extractor.askUser(Q_NUCLEAR_WEAPONS) ) System.out.println (A_DEFENSE_CONTRACTOR); else System.out.println (A_PUBLIC_DANGER); } else System.out.println (A_START_OVER); } else if ( extractor.askUser(Q_WINNT) ){ if ( extractor.askUser(Q_NUCLEAR_WEAPONS) ) System.out.println (A_DEFENSE_CONTRACTOR); else System.out.println (A_PUBLIC_DANGER); } else System.out.println (A_START_OVER); 15 HW J3 Code with methods The yellow boxed part is what was repeated from the previous slide if ( extractor.askUser(Q_TECH_SUPPORT) ){ if ( extractor.askUser(Q_BITTER_YET) ) if ( extractor.askUser(Q_MANAGEMENT) ) System.out.println (A_CYNICAL); else System.out.println (A_PROMOTED); else System.out.println (A_START_OVER); } else if ( extractor.askUser(Q_BEEN_SYSADMIN) ){ if ( extractor.askUser(Q_HATE_PEOPLE) ) { System.out.println (A_CODER); } else doBottomPartOfFlowchart(); } else doBottomPartOfFlowchart(); 16 HW J3 Code with methods The doBottomPartOfFlowchart method: public static void doBottomPartOfFlowchart() { if ( extractor.askUser(Q_WINNT) ){ if ( extractor.askUser(Q_NUCLEAR_WEAPONS) ) System.out.println (A_DEFENSE_CONTRACTOR); else System.out.println (A_PUBLIC_DANGER); } else System.out.println (A_START_OVER); } 17 What happened here We took a common set of code Wrote it once But used it multiple times (twice in this case) Granted, the code was a small segment (7 lines) But, in other programs, could be very large This is called Refactoring It is an essential principle of software engineering Has other names: factoring (notice there is no ‘re’ at the beginning), extracting a method, etc. 18 Pros of Refactoring Benefits of Refactoring Reduce length of code As you don’t have to repeat that section of code multiple times Make code easier to read The main if-else-if statement is shorter, thus easier to understand what’s going on Changes are easier to make If we want to modify that part of the flowchart, we only have to do it once Rather than searching for each of the repeated code segments in a program 19 Cons of Refactoring Drawbacks of Refactoring Because you are calling another method, it will be slightly slower On the order of a few nanoseconds Modern compilers can sometimes eliminate this penalty The general consensus is that the benefits of Refactoring far outweigh the drawback(s) 20 Return Values 22 The return keyword The return keyword immediately stops execution of a method And jumps back to whatever called that method And possibly returns a value (we’ll see this next) Consider the following method public static void foo (int x) { if ( x == 1 ) return; System.out.println (“x is not 1”); } This method will only print the String if x is not 1 23 Return values At some point in those methods, Java must be told to take a value and “pass” it back Consider angleSin = Math.sin (90 * PI/180.0); At some point in the Math.sin() method, the sin has been computed And that value must be “passed back” to be stored in angle Consider value = card.getBlackjackValue(); At some point in the card.getBlackjackValue() method, the value has been computed And that value must be “passed back” to be stored in value This is called “returning” a value from a method Note that some methods don’t return a value System.out.println(), for example 24 Return values (aka return types) public class Methods2 { public static int returnsAValue () { return 1; } public static double alsoReturnsAValue() { return 1.0; } public static void main (String args[]) { int value1 = returnsAValue(); System.out.println (value1); double value2 = alsoReturnsAValue(); System.out.println (value2); } } // The following line requires a cast int value3 = (int) alsoReturnsAValue(); System.out.println (value3); 25 Program Demo Methods2.java 26 Return types All a return statement does is take the value Which could be a number Or a value in a variable Or an expression (such as x+1) And “pass” it back to whatever called the method 27 How well do you feel you understand return values? a) b) c) d) e) Very well! This stuff is so easy. With a little review, I’ll be good. Not very well at all. I’m so lost. What’s a return type again? I’d rather not answer this question, thanks. 28 Parameters Sometimes you need to pass in parameters to tell a method how to perform Consider Math.sin() – it needs to know the angle The parameters are listed between the parenthesis after the method name public static void main (String args[]) The methods we will study next compute (and return) x2, x3, and x4 29 The methods public static int square (int x) { int theSquare = x * x; return theSquare; } public static int cube (int x) { return x * x * x; } public static int fourthPower (int x) { return square(x) * square(x); } 30 A method with multiple parameters public static int squareOrCube (int which, int value) { if ( which == 1 ) return value * value; else if ( which == 2 ) { int cube = value * value * value; return cube; } else return 0; } 31 The main() method import java.util.*; public class Methods3 { // the previous methods go here public static void main (String args[]) { Scanner stdin = new Scanner (System.in); System.out.println ("Enter an int value"); int value = stdin.nextInt(); int theSquare = square(value); System.out.println ("Square is " + theSquare); System.out.println ("Cube is " + cube (value)); System.out.println ("Square is " + squareOrCube (1, value)); System.out.println ("Cube is " + squareOrCube (2,value)); System.out.println ("Fourth power is " + fourthPower (value)); } 32 } Program Demo Methods3.java 33 The 2006 Ig Nobel Prizes Ornithology Nutrition Peace Acoustics Mathematics Literature Medicine Physics Chemistry Biology For explaining why woodpeckers don’t get headaches For showing that Kuwaiti dung beetles are finicky eaters For development of a high-pitched electronic teen-ager repellent (and, later, ring tones) For experiments to determine why people don’t like the sound of fingernails scraping on a blackboard For calculating the number of photos you must take to ensure that (almost) nobody in a group will have their eyes closed For a report entitled, “Consequences of Erudite Vernacular Utilized Irrespective of Necessity: Problems with Using Long Words Needlessly.“ For a medical case report titled, “"Termination of Intractable Hiccups with Digital Rectal Massage“ For studying why dry spaghetti breaks into multiple pieces For a study entitled, “Ultrasonic Velocity in Cheddar Cheese as Affected by Temperature," For showing that the female malaria mosquito is equally attracted to the smells of limburger cheese and human feet 34 Returning objects We can also return objects from methods What gets returned is the reference to the object name public class Methods4 { public static String getCourse () { String name = "CS 101"; return name; } public static void main (String args[]) { String courseName = getCourse(); System.out.println (courseName); } } String “CS 101” courseName 35 Program Demo Methods4.java 36 Modifying parameters Consider the following code public class Methods5 { public static void changeValue (int x) { x = 7; } public static void main (String args[]) { int y = 5; changeValue(y); System.out.println (y); } } What gets printed? 37 Program Demo Methods5.java 38 Pass by value Java is a pass-by-value language This means that a COPY of the parameter’s value is passed into the method If a method changes that value, only the COPY is changed Once the method returns, the copy is forgotten And thus the change is not visible outside the method There are other manners of returning values that are used in other languages Pass by reference Pass by name (nobody uses this anymore) We will see about trying to change object parameters later in this slide set 39 How well do you feel you understand parameters? a) b) c) d) e) Very well! This stuff is so easy. With a little review, I’ll be good. Not very well at all. I’m so lost. What’s a return type again? I’d rather not answer this question, thanks. 40 Variable scoping A variable is visible within the block it is declared Called the “scope” of the variable public class Scoping { static int z This variable is visible anywhere in the Scoping class public static void foo (int x) { // ... } This parameter is visible only in the foo() method public static void bar () { // ... } public static void main (String[] args) { int y; This local variable is visible until // ... the end of the main() method } } 41 Method notes summary You can put the methods in a class in any order Java doesn’t care which one is listed first Thus, you can call a method listed later in the method This is different than C/C++ All methods must specify a return type If it’s void, then no value is returned Parameters can’t be changed within a method Although the objects that the parameters point to can be 42 How well do you feel you understand scoping? a) b) c) d) e) Very well! This stuff is so easy. With a little review, I’ll be good. Not very well at all. I’m so lost. What’s a return type again? I’d rather not answer this question, thanks. 43 Today’s demotivators 44 The Car class 45 More on classes vs. objects 46 A new example: creating a Car class What properties does a car have in the real world? Color Position (x,y) Fuel in tank We will implement these properties in our Car class public class Car { private Color color; private int xpos; private int ypos; private int fuel; //... } 47 Car’s instance variables public class Car { private Color color; private int xpos; private int ypos; private int fuel; //... Car } - color - fuel - xpos - ypos +… 48 Instance variables and attributes Default initialization If the variable is within a method, Java does NOT initialize it If the variable is within a class, Java initializes it as follows: Car Numeric instance variables initialized to 0 - color = null - xpos = 0 - fuel = 0 - ypos = 0 Logical instance variables initialized to +… false Object instance variables initialized to null 49 Car behaviors or methods What can a car do? And what can you do to a car? Move it Change it’s x and y positions Change it’s color Fill it up with fuel For our computer simulation, what else do we want the Car class to do? Create a new Car Plot itself on the screen Each of these behaviors will be written as a method 50 Creating a new car To create a new Car, we call: Car c = new Car(); Notice this looks like a method You are calling a special method called a constructor A constructor is used to create (or construct) an object It sets the instance variables to initial values The constructor: public Car() { fuel = 1000; color = Color.BLUE; } 51 Constructors No return type! For now, all constructors are public EXACT same name as class public Car() { fuel = 1000; color = Color.BLUE; } 52 Our Car class so far public class Car { private Color color; private int xpos; private int ypos; private int fuel; public class Car { private Color color = Color.BLUE; private int xpos; private int ypos; private int fuel = 1000; public Car() { fuel = 1000; color = Color.BLUE; } } public Car() { } } 53 Our Car class so far public class Car { private Color color = Color.BLUE; private int xpos = 0; private int ypos = 0; private int fuel = 1000; Car - color = Color.BLUE - fuel = 1000 - xpos = 0 - ypos = 0 + Car() +… public Car() { } } Called the default constructor The default constructor has no parameters If you don’t include one, Java will SOMETIMES put one 54 there automatically Another constructor Another constructor: public Car (Color c, int x, int y, int f) { color = c; xpos = x; ypos = y; fuel = f; } This constructor takes in four parameters The instance variables in the object are set to those parameters This is called a specific constructor An constructor you provide that takes in parameters is called a specific constructor 55 Our Car class so far Car public class Car { private Color color = Color.BLUE; private int xpos = 0; private int ypos = 0; private int fuel = 1000; - color = Color.BLUE - fuel = 1000 - xpos = 0 - ypos = 0 + Car() + Car (Color, int, int, int) +… public Car() { } public Car (Color c, int x, int y, int f) { color = c; xpos = x; ypos = y; fuel = f; } } 56 Using our Car class Now we can use both our constructors: Car c1 = new Car(); Car c2 = new Car (Color.BLACK, 1, 2, 500); c1 c2 Car - color = Color.BLUE - fuel = 1000 Car - xpos = 0 - ypos = 0 + Car() + Car (Color, int, int, int) +… - color = Color.BLACK - xpos = 1 - fuel = 500 - ypos = 2 + Car() + Car (Color, int, int, int) +… 58 So what does private mean? Consider the following code Note that it’s a different class! public class CarSimulation { public static void main (String[] args) { Car c = new Car(); System.out.println (c.fuel); } } Recall that fuel is a private instance variable in the Car class Private means that code outside the class CANNOT access the variable For either reading or writing Java will not compile the above code 59 If fuel were public, the above code would work So how do we get the fuel of a Car? Via accessor methods in the Car class: public int getFuel() { return fuel; } public Color getColor() { return color; } public int getYPos() { return ypos; } public int getXPos() { return xpos; } As these methods are within the Car class, they can read the private instance variables As the methods are public, anybody can call them 60 So how do we set the fuel of a Car? Via mutator methods in the Car class: public void setFuel (int f) { fuel = f; } public void setColor (Color c) { color = c; } public void setXPos (int x) { xpos = x; } public void setYPos (int y) { ypos = y; } As these methods are within the Car class, they can read the private instance variables As the methods are public, anybody can call them 61 Why use all this? These methods are called a get/set pair Used with private variables We’ll see why one uses these later in this slide set Our Car so far: Car - color = Color.BLUE - fuel = 1000 - xpos = 0 - ypos = 0 + Car() + Car (Color, int, int, int) + void setXPos (int x) + void setYPos (int y) + void setColor (Color c) + void setFuel (int f) + int getFuel() + int getXPos() + int getYPos() + Color getColor() +… 62 Back to our specific constructor public class Car { private Color color = Color.BLUE; private int xpos = 0; private int ypos = 0; private int fuel = 1000; public class Car { private Color color = Color.BLUE; private int xpos = 0; private int ypos = 0; private int fuel = 1000; public Car (Color c, int x, int y, int f) { color = c; xpos = x; ypos = y; fuel = f; } } public Car (Color c, int x, int y, int f) { setColor (c); setXPos (x); setYPos (y); setFuel (f); } } 63 Back to our specific constructor Using the mutator methods (i.e. the ‘set’ methods) is the preferred way to modify instance variables in a constructor We’ll see why later 64 So what’s left to add to our Car class? What else we should add: A mutator that sets both the x and y positions at the same time A means to “use” the Car’s fuel A method to paint itself on the screen Let’s do the first: public void setPos (int x, int y) { setXPos (x); setYPos (y); } Notice that it calls the mutator methods 65 Using the Car’s fuel Whenever the Car moves, it should burn some of the fuel For each pixel it moves, it uses one unit of fuel We could make this more realistic, but this is simpler Math.abs() returns the absolute value public void setXPos (int x) { xpos = x; } public void setXPos (int x) { fuel -= Math.abs (getXPos()-x); xpos = x; } public void setYPos (int y) { ypos = y; } public void setYPos (int y) { fuel -= Math.abs (getYPos()-y); 66 ypos = y; Setting both positions at once public void setPos (int x, int y) { setXPos(x); setYPos(y); } Notice that to access the instance variables, the accessor methods are used 67 The 2005 Ig Nobel Prizes Agricultural history Physics Medicine Literature Peace Economics Chemistry Biology Nutrition Fluid dynamics “The Significance of Mr. Richard Buckley’s Exploding Trousers” The pitch drop experiment, started in 1927 Neuticles – artificial replacement testicles for dogs The 409 scams of Nigeria for a “cast of rich characters” Locust brain scans while they were watching Star Wars For an alarm clock that runs away, thus making people more productive “Will Humans Swim Faster or Slower in Syrup?” For cataloging the odors of 131 different stressed frogs To Dr. Yoshiro Nakamats who catalogued and analyzed every meal he ate for the last 34 years (and counting) “Pressures Produced When Penguins Pooh – Calculations on Avian Defaecation” 68 Drawing the Car The simple way to have the Car draw itself: public void paint (Graphics g) { g.setColor (color); g.fillRect (xpos-50, ypos-100, 100, 200); } This draws a single rectangle that is 100 by 200 pixels in size Lets use constants for the car’s height and width... 69 Drawing the Car A better version: private final int CAR_WIDTH = 100; private final int CAR_HEIGHT = 200; public void paint (Graphics g) { g.setColor (color); g.fillRect (getXPos()-CAR_WIDTH/2, getYPos()-CAR_HEIGHT/2, CAR_WIDTH, CAR_HEIGHT); } This makes it easier to change the car size We could have made the car size instance variables and set them via mutators Lets add tires! 70 Drawing the Car private private private private private final final final final final int int int int int CAR_WIDTH = 100; CAR_HEIGHT = 200; TIRE_WIDTH = 20; TIRE_HEIGHT = 40; TIRE_OFFSET = 20; public void paint (Graphics g) { g.setColor (color); g.fillRect (getXPos()-CAR_WIDTH/2, getYPos()-CAR_HEIGHT/2, CAR_WIDTH, CAR_HEIGHT); // Draw the tires g.setColor (Color.BLACK); g.fillRect (getXPos()-(CAR_WIDTH/2+TIRE_WIDTH), getYPos()-(CAR_HEIGHT/2-TIRE_OFFSET), TIRE_WIDTH, TIRE_HEIGHT); g.fillRect (getXPos()-(CAR_WIDTH/2+TIRE_WIDTH), getYPos()+(CAR_HEIGHT/2-TIRE_OFFSET-TIRE_HEIGHT), Don’t worry about TIRE_WIDTH, TIRE_HEIGHT); this – just know that g.fillRect (getXPos()+(CAR_WIDTH/2), it draws four tires getYPos()+(CAR_HEIGHT/2-TIRE_OFFSET-TIRE_HEIGHT), TIRE_WIDTH, TIRE_HEIGHT); g.fillRect (getXPos()+(CAR_WIDTH/2), getYPos()-(CAR_HEIGHT/2-TIRE_OFFSET), TIRE_WIDTH, TIRE_HEIGHT); } 71 What happens when the car runs out of fuel? We could do a number of things: Not allow the car to move anymore Print out a message saying, “fill me up!” We’ll color the car red We’ll insert the following code at the beginning of the paint() method: if ( fuel < 0 ) { color = Color.RED; } 72 Drawing the Car private private private private private final final final final final int int int int int CAR_WIDTH = 100; CAR_HEIGHT = 200; TIRE_WIDTH = 20; TIRE_HEIGHT = 40; TIRE_OFFSET = 20; public void paint (Graphics g) { if ( fuel < 0 ) { color = Color.RED; } g.setColor (color); g.fillRect (getXPos()-CAR_WIDTH/2, getYPos()-CAR_HEIGHT/2, CAR_WIDTH, CAR_HEIGHT); // Draw the tires g.setColor (Color.BLACK); g.fillRect (getXPos()-(CAR_WIDTH/2+TIRE_WIDTH), getYPos()-(CAR_HEIGHT/2-TIRE_OFFSET), TIRE_WIDTH, TIRE_HEIGHT); g.fillRect (getXPos()-(CAR_WIDTH/2+TIRE_WIDTH), getYPos()+(CAR_HEIGHT/2-TIRE_OFFSET-TIRE_HEIGHT), TIRE_WIDTH, TIRE_HEIGHT); g.fillRect (getXPos()+(CAR_WIDTH/2), getYPos()+(CAR_HEIGHT/2-TIRE_OFFSET-TIRE_HEIGHT), TIRE_WIDTH, TIRE_HEIGHT); g.fillRect (getXPos()+(CAR_WIDTH/2), getYPos()-(CAR_HEIGHT/2-TIRE_OFFSET), TIRE_WIDTH, TIRE_HEIGHT); } 73 Our car in action CarGUI.java 74 How well do you feel you understand the Car class? a) b) c) d) e) Very well! This stuff is so easy. With a little review, I’ll be good. Not very well at all. I’m so lost. What’s a car again? I’d rather not answer this question, thanks. 75 Fan-supplied demotivators! 76 Parameter passing 77 Modifying parameters Consider the following code public class Methods5 { public static void changeValue (int x) { x = 7; } x 5 7 y 5 public static void main (String args[]) { int y = 5; changeValue(y); System.out.println (y); } } What gets printed? 5 is printed 78 Program Demo Methods5.java 79 Pass by value Java is a pass-by-value language This means that a COPY of the parameter’s value is passed into the method If a method changes that value, only the COPY is changed Once the method returns, the copy is forgotten And thus the change is not visible outside the method There are other manners of returning values that are used in other languages Pass by reference Pass by name (nobody uses this anymore) We will see about trying to change object parameters later in this slide set 80 Modifying parameters Consider the following code import java.awt.*; Rectangle r public class Methods6 { public static void changeValue (Rectangle r) { r.setSize (10,20); } - width = 10 1 - height = 20 2 + Rectangle () + Rectangle (int width, int height) + setSize (int width, int height) + getWidth () public static void main (String args[]) { Rectangle rect = new Rectangle(1, 2); changeValue(rect); System.out.println (rect.getWidth()); } rect } What gets printed? 10 is printed 81 Program Demo Methods6.java 82 Pass by value Java is still a pass-by-value language This means that a COPY of the parameter’s value is passed into the method But the parameter is a REFERENCE to an object The object itself is not passed So any changes to the reference are forgotten about But you can modify the object it refers to 83 Rectangle Modifying parameters Consider the following code import java.awt.*; - width = 10 + Rectangle () + Rectangle (int width, int height) + setSize (int width, int height) + getWidth() r public class Methods7 { Rectangle - width = 1 public static void changeValue (Rectangle r) { r = new Rectangle (10,20); } What gets printed? 1 is printed - height = 2 + Rectangle () + Rectangle (int width, int height) + setSize (int width, int height) + getWidth() public static void main (String args[]) { Rectangle rect = new Rectangle(1, 2); changeValue(rect); System.out.println (rect.getWidth()); } } - height = 20 rect The only change! 84 Program Demo Methods7.java 85 Pass by value Java is still a pass-by-value language This means that a COPY of the parameter’s value is passed into the method But the parameter is a REFERENCE to an object The object itself is not passed So any changes to the reference are forgotten about But you can modify the object it refers to 86 How well do you feel you understand parameter passing? a) b) c) d) e) Very well! This stuff is so easy. With a little review, I’ll be good. Not very well at all. I’m so lost. What’s a parameter again? I’d rather not answer this question, thanks. 87 Yale vs. Harvard 88 Miscellaneous Stuff 90 What I’m not expecting you to know yet… What the static keyword means And why the main() method is And why other methods are not Why you should always call the mutator methods, instead of setting the field directly Just know that it’s a good programming practice, and follow it We’ll see why later Why instance variables are supposed to be private Just know that it’s a good programming practice, and follow it 91 Again, we’ll see why soon Terminology An attribute of a class can be called: Instance variable or class variable We’ll see the difference later Static variable (or static field) Synonymous with class variable Field Generally means either type Variable Also means either type Attribute Property Argh! I will generally use the terms variable or field when I am not differentiating between the two And instance variable/field and class variable/field when I am 92 The main() method Consider a class with many methods: public class WhereToStart { public static void foo (int x) { // ... } public static void bar () { // ... } public static void main (String[] args) { // ... } } Where does Java start executing the program? Always at the beginning of the main() method! 93 Running a class without a main() method Consider the Car class It had no main() method! The main() method was in the CarSimulation (or CarGUI) class So let’s try running it… 94 Program Demo Car.java 95 Variable initialization A local variable is NOT initialized to a default value This is any variable declared within a method Or within a block within a method This is pretty stupid, in my opinion Parameters are initialized to whatever value they are passed Instance and class variables are initialized to default values Numbers to zero, booleans to false, references to null This means any field in a class Either class variables or instance variables 96 How well do you feel you understand creating classes so far? a) b) c) d) e) Very well! This stuff is so easy. With a little review, I’ll be good. Not very well at all. I’m so lost. What’s a class again? I’d rather not answer this question, thanks. 97 Today’s demotivators 98 The Circle class Introducing static-ness, visibilities, etc. 100 A Circle class We are going to develop a Circle class Perhaps for use in a graphics program Why? Partly to review creating classes Go over some topics that were a bit fuzzy Constructors and creating objects Show why one uses the get/set methods instead of directly modifying the instance variables Discuss visibilities (public, private, etc.) Discuss the static keyword 101 Circle class properties What properties does a circle have? Radius PI = 3.141592653589793234 Color (if plotting in a graphics program) (x,y) location These properties will become instance variables We are only going to play with the first two (radius and PI) in this example Thus, we are ignoring the color and location 102 Our Circle class Circle c = new Circle(); c Note the radius field is not initialized by us public class Circle { double radius; double PI = 3.1415926536; } We’re ignoring the public for now Note the fields are not static Circle - radius = 0.0 - PI = 3.14159… -… +… 103 Accessing our Circle object Any variable or method in an object can be accessed by using a period The period means ‘follow the reference’ Example: System.in c Example: System.out.println (c.radius); Example: c.PI = 4; This is bad – PI should have been declared final (this will be done later) Circle - radius = 0.0 - PI = 3.14159… -… +… 104 What’s the output? public class Circle { double radius; double PI = 3.1415926536; } public class CircleTest { public static void main (String[] args) { int x; Circle c = new Circle(); System.out.println (x); Java will give a } “variable not } initialized” error When a variable is declared as part of a method, Java does not initialize it to a default value 105 What’s the output now? public class Circle { double radius; double PI = 3.1415926536; } public class CircleTest { public static void main (String[] args) { int x; Circle c = new Circle(); System.out.println (c.radius); Java } } outputs 0.0! When a variable is declared as part of a class, Java does initialize it to a default value 106 What’s going on? A (method) variable needs to be initialized before it is used Usually called a local variable A instance variable is automatically initialized by Java All numbers are initialized to 0, booleans to false, etc. This is a bit counter-intuitive… 107 Circle class behaviors What do we want to do with (and to) our Circle class? Create circles Modify circles (mutators) Find out about our circles’ properties (accessors) Find the area of the circle Plot it on the screen (or printer) A few others… These will be implemented as methods 108 Calling the Circle constructor To create a Circle object: c1 Circle c1 = new Circle(); This does four things: Creates the c1 reference Creates the Circle object Makes the c1 reference point to the Circle object Calls the constructor with no parameters (the ‘default’ constructor) Circle - radius = 0.0 - PI = 3.14159… -… + Circle() + Circle (double r) +… The constructor is always the first method called when creating (or ‘constructing’) an object 109 Calling the Circle constructor To create a Circle object: c1 Circle c1 = new Circle(2.0); This does four things: Creates the c1 reference Creates the Circle object Makes the c1 reference point to the Circle object Calls the constructor with 1 double parameters (the ‘specific’ constructor) Circle - radius = 0.0 - PI = 3.14159… -… + Circle() + Circle (double r) +… The constructor is always the first method called when creating (or ‘constructing’) an object 110 Constructors Remember, the purpose of the constructor is to initialize the instance variables PI is already set, so only radius needs setting public Circle() { radius = 1.0; } public Circle (double r) { radius = r; } Note there is no return type for constructors Note that the constructor name is the EXACT same as the class name Note that there are two “methods” with the same name! 111 What happens in memory Consider: Circle c = new Circle(); A double takes up 8 bytes in memory Thus, a Circle object takes up 16 bytes of memory As it contains two doubles Circle c - radius = 1.0 - PI = 3.1415926536 -… + Circle() + Circle (double r) +… Shorthand representation c Circle - radius = 1.0 - PI = 3.14159 112 Circle class: our class so far public class Circle { double radius; double PI = 3.1415926536; public Circle() { radius = 1.0; } public Circle (double r) { radius = r; } } 113 How well do you feel you understand the Constructors? a) b) c) d) e) Very well! This stuff is so easy. With a little review, I’ll be good. Not very well at all. I’m so lost. What’s a class again? I’d rather not answer this question, thanks. 114 What do these pictures mean? Light beer Dandy lions Assaulted peanut Eggplant Dr. Pepper Pool table Tap dancers Card shark King of pop I Pod Gator aide Knight mare Hole milk 115 Circle class: our class so far public class Circle { double radius; double PI = 3.1415926536; public Circle() { radius = 1.0; } public Circle (double r) { radius = r; } } 116 Consider the following code public class CircleTest { public static void main (String[] args) { Circle c1 = new Circle(); Circle c2 = new Circle(); Circle c3 = new Circle(); Circle c4 = new Circle(); } } 117 What happens in memory There are 4 Circle objects in memory Taking up a total of 4*16 = 64 bytes of memory c1 Circle - radius = 1.0 - PI = 3.14159 c2 Circle - radius = 1.0 - PI = 3.14159 c3 Circle - radius = 1.0 - PI = 3.14159 c4 Circle - radius = 1.0 - PI = 3.14159 118 Consider the following code public class CircleTest { public static void main (String[] args) { Circle c1 = new Circle(); //... Circle c1000000 = new Circle(); } } public class CircleTest { public static void main (String[] args) { Vector v = new Vector(); for ( int i = 0; i < 1000000; i++ ) v.add (new Circle()); } } These programs create 1 million Circle objects! 119 What happens in memory There are 1 million Circle objects in memory Taking up a total of 1,000,000*16 ≈ 16 Mb of memory c1 c2 Circle - radius = 1.0 - PI = 3.14159 Circle - radius = 1.0 - PI = 3.14159 c1000000 … Circle - radius = 1.0 - PI = 3.14159 Note that the final PI field is repeated 1 million times 120 The use of static for fields If a variable is static, then there is only ONE of that variable for ALL the objects That variable is shared by all the objects 16 (1+1=2 doubles) Total memory Total usage: memory 8 Mb usage: + 8 40 bytes bytes (1,000,000+1=1,000,001 (4+1=5 doubles) c1 c2 c3 Circle Circle - radius = 1.0 - radius = 1.0 PI … c1000000 c4 Circle Circle - radius = 1.0 - radius = 1.0 3.1415926536 121 More on static fields What does the following print Note that PI is not final Circle c1 = new Circle(); Circle c2 = new Circle(); Circle c3 = new Circle(); Circle c4 = new Circle(); c1.PI = 4.3; System.out.println (c2.PI); Note you can refer to static fields by object.variable It prints 4.3 122 Even more on static fields There is only one copy of a static field no matter how many objects are declared in memory Even if there are zero objects declared! The one field is “common” to all the objects Static variables are called class variables As there is one such variable for all the objects of the class Whereas non-static variables are called instance variables Thus, you can refer to a static field by using the class name: Circle.PI 123 Even even more on static fields This program also prints 4.3: Circle c1 = new Circle(); Circle c2 = new Circle(); Circle c3 = new Circle(); Circle c4 = new Circle(); Circle.PI = 4.3; System.out.println (c2.PI); 124 Even even even more on static fields We’ve seen static fields used with their class names: System.in (type: InputStream) System.out (type: OutputStream) Math.PI (type: double) Integer.MAX_VALUE (type: int) Game.BOARD_X_COORD (in HW J6) 125 How well do you feel you understand static-ness? a) b) c) d) e) Very well! This stuff is so easy. With a little review, I’ll be good. Not very well at all. I’m so lost. What’s a class again? I’d rather not answer this question, thanks. 126 New 2005 demotivatiors! 127 Back to our Circle class public class Circle { double radius; final static double PI = 3.1415926536; public Circle() { radius = 1.0; } Note that PI is now final and static public Circle (double r) { radius = r; } } But it doesn’t do much! 128 Adding a method public class Circle { double radius; final static double PI = 3.1415926536; // Constructors... double computeArea () { return PI*radius*radius; } } Note that a (non-static) method can use both instance and class variables 129 Using that method public class CircleTest { public static void main (String[] args) { Circle c = new Circle(); c.radius = 2.0; double area = c.computeArea(); System.out.println (area); } } Prints 12.566370614356 130 What happens when that method is called public class Circle { double radius; final static double PI = 3.1415926536; public Circle() { radius = 1.0; } c area 12.566 // other constructor double computeArea () { return PI*radius*radius; } } public class CircleTest { public static void main (String[] args) { Circle c = new Circle(); c.radius = 2.0; double area = c.computeArea(); System.out.println (area); } } Circle - radius = 2.0 0.0 1.0 - PI = 3.14159… -… + Circle() + Circle (double r) + computeArea() +… 131 Review of our Circle class public class Circle { double radius; final static double PI = 3.1415926536; public Circle() { } Slight change from before public Circle (double r) { radius = r; } double computeArea () { return PI*radius*radius; } } 132 A note about methods/variable order Within a method, a variable must be declared before it is used In a class, methods and variables can be declared in any order This is different than C++ 133 Adding another method double oneOverRadius() { return 1.0/radius; } I couldn’t think of a good reason to divide something by the radius… 134 What happens now? Code in class CircleTest’s main() method Circle c = new Circle(); // c.radius is now 0.0 System.out.println (c.oneOverRadius()); Java won’t crash, but many other programming languages (C and C++, in particular) will So we’ll call this a ‘crash’ for the sake of this lecture Java prints “Infinity” Not what we wanted, though! 135 One way to fix this… public class Circle { double radius = 1.0; final static double PI = 3.1415926536; Note that the radius variable is now initialized to 1.0 // Constructors... double computeArea () { return PI*radius*radius; } double oneOverRadius() { return 1.0/radius; } } 136 Back to our program… This code will now run properly: Circle c = new Circle(); // c.radius = 1.0 System.out.println (c.oneOverRadius()); But this code will “crash”: Circle c = new Circle(); // c.radius = 1.0 c.radius = 0.0; System.out.println (c.oneOverRadius()); 137 Where the “crash” occurs public class CircleTest { public static void main (String[] args) { Circle c = new Circle(); // c.radius = 1.0 c.radius = 0.0; System.out.println (c.oneOverRadius()); } } Here is the badly written code public class Circle { double radius = 1.0; final static double PI = 3.1415926536; double computeArea () { return PI*radius*radius; } double oneOverRadius() { return 1.0/radius; } Here is where the “crash” occurs 138 Motivation for private fields Problem: We do not want people using our Circle class to be able to modify the fields on their own Solution: Don’t allow other code to modify the radius field Give it private visibility private means that only code within the class can modify the field 139 One way to fix this… public class Circle { private double radius = 1.0; final static double PI = 3.1415926536; Note that the radius variable is now private // Constructors... double computeArea () { return PI*radius*radius; } double oneOverRadius() { return 1.0/radius; } } 140 From Dubai 141 Back to our program… This code will now not compile: Circle c = new Circle(); // c.radius = 1.0 c.radius = 0.0; System.out.println (c.oneOverRadius()); Java will give a compile-time error: radius has private access in Circle 142 Back to our program… This code will also not compile: Circle c = new Circle(); // c.radius = 1.0 System.out.println (c.radius); Java will give the same compile-time error: radius has private access in Circle 143 The problem now… But now you can’t modify a Circle’s radius! Or find out what it is Solution: Use a get/set methods in Circle: A mutator method: void setRadius (double r) { radius = r; } An accessor method: double getRadius () { return radius; } 144 Our Circle class so far public class Circle { private double radius = 1.0; final static double PI = 3.1415926536; // Constructors... double computeArea () { return PI*radius*radius; } double oneOverRadius() { return 1.0/radius; } void setRadius (double r) { radius = r; } double getRadius () { return radius; } } 145 Using the get/set methods public class CircleTest { public static void main (String[] args) { public class Circle { private double radius = 1.0; final static double PI = 3.1415926536; double computeArea () { return PI*radius*radius; } Circle c = new Circle(); c.setRadius (1.0); double oneOverRadius() { return 1.0/radius; } System.out.println (c.computeArea()); void setRadius (double r) { radius = r; } System.out.println (c.getRadius()); } double getRadius () { return radius; } } Here a method is invoked } 146 Here the change to radius occurs Wait! Another problem! public class CircleTest { public static void main (String[] args) { Circle c = new Circle(); c.setRadius (0.0); Here is the problem now… System.out.println (c.oneOverRadius()); } } 147 This problem is easily fixed Change the setRadius() method to the following void setRadius (double r) { if ( r > 0.0 ) radius = r; else radius = 1.0; } Now there is (almost) no way for code outside the Circle class to change the radius to zero This is the purpose of mutators To prevent changing the fields to a “bad” value We’ll see another motivation in a bit 148 Review of static for fields If a variable is static, then there is only ONE of that variable for ALL the objects That variable is shared by all the objects 16 (1+1=2 doubles) Total memory Total usage: memory 8 Mb usage: + 8 40 bytes bytes (1,000,000+1=1,000,001 (4+1=5 doubles) c1 c2 c3 Circle Circle - radius = 1.0 - radius = 1.0 PI … c1000000 c4 Circle Circle - radius = 1.0 - radius = 1.0 3.1415926536 150 Visibilities in Java There are four visibilities: private: Only code within the same class can access the field or method Note: “access” means reading or writing the field, or invoking the method public: Any code, anywhere, can access the field or method protected: Used with inheritance We won’t get to that this semester default: Almost the same as public This is the default (duh!) Note that it can’t be specified like the others Also called ‘package’ 151 A few notes on visibilities You can NOT specify visibilities for method variables Any method variable can only be accessed within that method Think of it as public within the method (after it’s defined) and private outside the method You can also specify visibilities for methods and classes We will see this a bit in this course 152 How well do you feel you understand visibilities? a) b) c) d) e) Very well! This stuff is so easy. With a little review, I’ll be good. Not very well at all. I’m so lost. What’s a class again? I’d rather not answer this question, thanks. 153 Overriding methods (and constructors) Consider the following code: Circle c1 = new Circle (); Circle c2 = new Circle (2.0); Creates a Circle of radius 1.0 Creates a Circle of radius 2.0 Java knows which constructor to call by the list of parameters This is called “overloading” Meaning it means multiple things, depending on the context We’ve seen overloading before: 3+4 Performs integer addition 3.0+4.0 Performs floating-point addition “3”+”4” Performs string concatenation The ‘+’ operator is overloaded 154 Overriding methods (and constructors), take 2 The following Circle constructors would not be allowed: We are assuming PI is not final for this example public Circle() { radius = 1.0; } public Circle (double r) { radius = r; } When Circle(1.0) is called, which one is meant? public Circle (double p) { PI = p; } 155 Using mutators in the constructor Our second constructor has a problem: public Circle (double r) { radius = r; } Consider the following code: Circle c = new Circle (0.0); System.out.println (c.oneOverRadius()); The method is dividing by zero (again) 156 Using mutators in the constructor This is easily fixed! Our revised constructors: public Circle() { setRadius (1.0); } public Circle (double r) { setRadius (r); } The mutator will properly set the radius (and won’t set it to zero) 157 Chapter 2: Computer bugs 158 Why we always use the mutators Consider a modified version of our circle class: class Circle { double radius; double diameter; String size; // ... Our mutator now looks like this: That’s a lot of code to copy if you decide not to call the mutator! void setRadius (double r) { if ( radius <= 0.0 ) radius = 1.0; else radius = r; diameter = 2*radius; if ( radius < 1.0 ) size = “small”; else if ( radius < 5.0 ) size = “medium”; else if ( radius < 10.0 ) size = “large”; else size = “huge”; } 159 Back to the static discussion Remember that there is one (and only one) static PI field, regardless of how many objects are declared Consider the following method: double getPI() { return PI; } It doesn’t read or modify the “state” of any object In this example, it doesn’t read/write the radius In fact, that particular method doesn’t care anything about the objects declared It’s only accessing a static field 160 Make getPI() static Consider the following: static double getPI() { return PI; } As the method is static, it can ONLY access static fields A static method does not care about the “state” of an object Examples: Math.sin(), Math.tan(), Math.cos() They don’t care about the state of any Math object They only perform the computation 161 Invoking static methods As with static fields, they can be called using either an object or the class name: Circle c = new Circle(); System.out.println (c.getPI()); System.out.println (Circle.getPI()); Static methods are also called class methods 162 static methods and non-static fields Consider the following (illegal) Circle method: static double getRadius() { return radius; } And the code to invoke it: public static void main (String[] args) { Circle c1 = new Circle(); Circle c2 = new Circle(); Circle c3 = new Circle(); Circle c4 = new Circle(); System.out.println (Circle.getRadius()); } 163 What happening in memory There are no 4 million 1 Circle Circleobjects Circle objects objects ininmemory memory in memory Which radius field does Circle.getRadius() want? c1 c2 c3 Circle Circle - radius = 1.0 - radius = 1.0 PI … c1000000 c4 Circle Circle - radius = 1.0 - radius = 1.0 3.1415926536 164 The main static lesson A static method cannot access or modify the state of the object it is a part of If you remember remember this! nothing else about static methods, 165 static and non-static rules Non-static fields and methods can ONLY be accessed by the object name Static fields and methods can be accessed by EITHER the class name or the object name Non-static methods can refer to BOTH static and non-static fields Static methods can ONLY access static fields of the class they are part of 166 How well do you feel you understand static-ness? a) b) c) d) e) Very well! This stuff is so easy. With a little review, I’ll be good. Not very well at all. I’m so lost. What’s a class again? I’d rather not answer this question, thanks. 167 Back to our main() method public static void main (String[] args) We’ll learn about arrays in chapter 8 The method does not return a value Any code anywhere can call this method It’s a static method: •Can’t access non-static fields or methods directly •Can be called only by the class name 168 Implications of main() being static It can call other static methods within the same class class StaticMethods { static void method1() { System.out.println (“hi!”); } public static void main (String args[]) { method1(); } } Note that we didn’t have to prefix method1() with a object Java assumes that it is in the same class 169 Another use of static methods Let’s say we want each Circle object to have a unique identifier The identifier will be a positive integer So in the Circle class, we add a instance variable: int id = 0; Thus, each Circle object will have it’s own id number To keep track of the last assigned id number, we will use a class variable static int lastAssignedID = 0; Thus, for all Circle objects created, we will have a single 170 lastAssignedID field Circle ID numbers We can then create a method to obtain a unique ID number: public static int getID() { return ++lastAssignedID; } This method is static, and only can access static fields In our Circle constructors, we put the following line: id = getID(); 171 Alien Song AlienSong.mpg 172 More on methods 174 Calling a method Consider two Strings: String s = “foo”; String t = “bar”; Calling s.substring(2) is different than calling t.substring(2) Why? Because of the object it is being called out of The method works the same in both cases (returns the substring) But it returns different results Whenever we are calling a method, we also need to know which object we are calling it out of 175 Return values Many methods return a value Math.cos() String.valueOf() Consider: double d = Math.cos (90 * Math.PI/180.0); Let’s consider the Math.cos() method public double cos (double a) { double c = 0.0; // compute cos somehow into a variable c return c; } The value c in the cos() method is copied into d 176 The return keyword The return keyword does a few things: Immediately terminate the current method Pass the value back to whoever called the method You can have a return anywhere you want Inside loops, ifs, etc. You can have as may returns as you want as well: public if ( else else } String x == 1 if ( x return foo (int x) { ) return “one”; == 2 ) return “two”; “other”; 177 More on returns Consider this class: public class Foo { // Default constructor omitted on this slide public String bar (String s) { String t = “CS 101” + “ ” + s; return t; } } And the code to invoke it: Foo w = new Foo(); String x = “rules”; String y = foo.bar (x); System.out.println (y); What happens in memory? 178 Foo w = new Foo(); String x = “rules”; String y = w.bar (x); System.out.println (y); x s t w this “rules" “CS 101 rules" y Foo + Foo() + bar (String s): String +… public String bar (String s) { String t = “CS 101” + “ ” + s; return t; } 179 Returning an object from a method We could rewrite our bar() method a number of ways: public String bar (String s) { String t = “CS 101” + “ ” + s; return t; } public String bar (String s) { return new String (“CS 101” + “ ” + s); } public String bar (String s) { return “CS 101” + “ ” + s; } 180 Returning a non-object from a method In other words, returning a primitive type from a method public foo () { // ... return x + y; } This method evaluates x+y, then returns that value to the caller 181 End of slides gone over in lecture We will not be going over the remaining slides in this slide set. 182 Rational class 183 What we’ve seen so far An example of creating a class Car Up next: another example Rational Represents rational numbers A rational number is any number that can expressed as a fraction Both the numerator and denominator must integers! Discussed in section 4.8 of the textbook 184 be be What properties should our Rational class have? The numerator (top part of the fraction) The denominator (bottom part of the fraction) Not much else… 185 What do we want our Rational class to do? Obviously, the ability to create new Rational objects Setting the numerator and denominator Getting the values of the numerator and denominator Perform basic operations with rational numbers: + - * / Ability to print to the screen 186 Our first take at our Rational class Our first take public class Rational { private int numerator; private int denominator; //... } Rational - numerator = 0 - denominator = 0 +… This does not represent a valid Rational number! Why not? Java initializes instance variables to zero Both the numerator and denominator are thus set to zero 0/0 is not a valid number! 187 Our next take at our Rational class Our next take public class Rational { private int numerator = 0; private int denominator = 1; //... } We’ve defined the attributes of our class Rational - numerator = 0 - denominator = 1 +… Next up: the behaviors 188 The default constructor Ready? Rational - numerator = 0 - denominator = 1 public Rational() { } + Rational() +… Yawn! Note that we could have initialized the instance variables here instead The default constructor is called that because, if you don’t specify ANY constructors, then Java includes one by default 189 Default constructors do not take parameters The specific constructor Called the specific constructor because it is one that the user specifies They take one or more parameters public Rational (int num, int denom) { setNumerator (num); Rational setDenominator (denom); - numerator = 0 - denominator = 1 } Note that the specific constructor calls the mutator methods instead of setting the instance variables directly We’ll see why later + Rational() + Rational (int num, int denom) +… 190 Accessor methods Our two accessor methods: public int getNumerator () { return numerator; } public int getDenominator () { return denominator; } Rational - numerator = 0 - denominator = 1 + Rational() + Rational (int num, int denom) + int getNumerator() + int getDemonimator() +… 191 Mutator methods Our two mutator methods: public void setNumerator (int towhat) { numerator = towhat; } public void setDenominator (int towhat) { denominator = towhat; } 192 Rational addition How to do Rational addition: a c ad bc b d bd Our add() method: public Rational add (Rational other) { } 193 The this keyword Rational Returns: - numerator = 5 - denominator = 6 + Rational () + Rational (int n, int d) + Rational add (Rational other) +… this Rational Rational - numerator = 1 - denominator = 2 - numerator = 1 - denominator = 3 + Rational () + Rational (int n, int d) + Rational Rational add add(Rational (other other) ) +… + Rational () + Rational (int n, int d) + Rational add (Rational other) +… 194 The this keyword this is a reference to whatever object we are currently in Will not work in static methods We’ll see why later Note that the main() method is a static method While we’re at it, when defining a class, note that NONE of the methods so far were static 195 Rational addition How to do Rational addition: a c ad bc b d bd Our add() method: public Rational add (Rational other) { int a = this.getNumerator(); int b = this.getDenominator(); int c = other.getNumerator(); int d = other.getDenominator(); return new Rational (a*d+b*c, b*d); } 196 Rational addition The following method is equivalent: Our add() method: public Rational add (Rational other) { int a = getNumerator(); int b = getDenominator(); int c = other.getNumerator(); int d = other.getDenominator(); return new Rational (a*d+b*c, b*d); } 197 Rational addition The following method is equivalent, but not preferred: Our add() method: public Rational add (Rational other) { int a = numerator; int b = denominator; int c = other.numerator; int d = other.nenominator; return new Rational (a*d+b*c, b*d); } 198 Rational addition The following method is equivalent, but not preferred: Our add() method: public Rational add (Rational other) { int a = this.numerator; int b = this.denominator; int c = other.numerator; int d = other.nenominator; return new Rational (a*d+b*c, b*d); } 199 Rational subtraction How to do Rational subtraction: a c ad bc b d bd Our subtract() method: public Rational subtract (Rational other) { int a = this.getNumerator(); int b = this.getDenominator(); int c = other.getNumerator(); int d = other.getDenominator(); return new Rational (a*d-b*c, b*d); } 200 Rational multiplication How to do Rational multiplication: a c ac * b d bd Our multiply() method: public Rational multiply (Rational other) { int a = this.getNumerator(); int b = this.getDenominator(); int c = other.getNumerator(); int d = other.getDenominator(); return new Rational (a*c, b*d); } 201 Rational division How to do Rational division: a c ad b d bc Our divide() method: public Rational divide (Rational other) { int a = this.getNumerator(); int b = this.getDenominator(); int c = other.getNumerator(); int d = other.getDenominator(); return new Rational (a*d, b*c); } 202 Printing it to the screen If we try printing a Rational object to the screen: Rational r = new Rational (1,2); System.out.println (r); We get the following: Rational@82ba41 Ideally, we’d like something more informative printed to the screen The question is: how does Java know how to print a custom 203 class to the screen? The toString() method When an object is put into a print statement: Rational r = new Rational (1,2); System.out.println (r); Java will try to call the toString() method to covert the object to a String If the toString() method is not found, a default one is included Hence the Rational@82ba41 from the previous slide So let’s include our own toString() method 204 The toString() method Our toString() method is defined as follows: public String toString () { return getNumerator() + "/" + getDenominator(); } Note that the prototype must ALWAYS be defined as shown The prototype is the ‘public String toString()’ 205 Printing it to the screen Now, when we try printing a Rational object to the screen: Rational r = new Rational (1,2); System.out.println (r); We get the following: 1/2 Which is what we wanted! Note that the following two lines are (mostly) equivalent: System.out.println (r); System.out.println (r.toString()); 206 Our full Rational class Rational - numerator = 0 - denominator = 1 + Rational() + Rational (int num, int denom) + int getNumerator() + int getDemonimator() + void setNumerator (int num) + void setDenominator (int denom) + Rational add (Rational other) + Rational subtract (Rational other) + Rational multiply (Rational other) + Rational divide (Rational other) + String toString() 207 Our Rational class in use, part 1 of 4 This code is in a main() method of a RationalDemo class First, we extract the values for our first Rational object: Scanner stdin = new Scanner(System.in); System.out.println(); // extract values for rationals r and s Rational r = new Rational(); System.out.print("Enter numerator of a rational number: "); int a = stdin.nextInt(); System.out.print("Enter denominator of a rational number: "); int b = stdin.nextInt(); r.setNumerator(a); r.setDenominator(b); 208 Our Rational class in use, part 2 of 4 Next, we extract the values for our second Rational object: Rational s = new Rational(); System.out.print("Enter numerator of a rational number: "); int c = stdin.nextInt(); System.out.print("Enter denominator of a rational number: “); int d = stdin.nextInt(); s.setNumerator(c); s.setDenominator(d); Notice that I didn’t create another Scanner object! Doing so would be bad I used the same one 209 Our Rational class in use, part 3 of 4 Next, we do the arithmetic: // operate on r and s Rational sum = r.add(s); Rational difference = r.subtract(s); Rational product = r.multiply(s); Rational quotient = r.divide(s); 210 Our Rational class in use, part 4 of 4 Lastly, we print the results // display operation results System.out.println("For r = " + r.toString() + " and s = " + s.toString()); System.out.println(" r + s = " + sum.toString()); System.out.println(" r - s = " + difference.toString()); System.out.println(" r * s = " + product.toString()); System.out.println(" r / s = " + quotient.toString()); System.out.println(); 211 A demo of our Rational class RationalDemo.java 212 Other things we might want to add to our Rational class The ability to reduce the fraction So that 2/4 becomes 1/2 Not as easy as it sounds! More complicated arithmetic Such as exponents, etc. Invert Switches the numerator and denominator Negate Changes the rational number into its (additive) negation We won’t see any of that here 213 How well do you feel you understand the Rational class? a) b) c) d) e) Very well! This stuff is so easy. With a little review, I’ll be good. Not very well at all. I’m so lost. What’s a class again? I’d rather not answer this question, thanks. 214