UC3M Alberto Cortés Martín Systems Programming, 2014-2015 version: 2015-02-06 Session 04 - Object-Oriented Programming 1 Self-Assessment Exercise 1 Rectangles Part 1.A Write a class called Rectangle1 that stores the width and height of a rectangle in public attributes. It must have a constructor that receives the width and height of the rectangle. This constructor should throw an exception if any of these parameters are zero or negative. Part 1.B Write a program called Rectangle1TestException to test if creating a Rectangle1 with an invalid width or height throws an exception. The program must print Exception caught! if the exception is caught. If the exception is not caught, it must print Exception NOT caught. Modify the code of the program, changing the parameters to the rectangle constructor, compile again and run it, to test both situations. Part 1.C Make the necessary changes to your Rectangle1 class so that the following program behaves as the example below. Rectangle1Test.java 1 class Rectangle1Test { 3 try { 4 Rectangle1 r = new Rectangle1(1D, 3D); 5 System.out.println(r); 6 } catch (Exception ex) { 7 System.out.println(ex.getMessage()); 8 } 9 } 10 } 1 $ java Rectangle1Test 2 Rectangle: width = 1.0 and height = 3.0 1
Part 1.D Given that the width and the height should be greater than 0, do you think the width and height attributes of the Rectangle1 class should be public? Why not? Write a program called BreakARectangle1 that creates a valid Rectangle1, then change its width or its height to some invalid value and then prints the rectangle. $ java BreakARectangle1 Rectangle: width = -1.0 and height = 3.0 Part 1.E Fix the class Rectangle1 by writing a new version called Rectangle2 that protects the attributes of the rectangle from the user by making them private. Part 1.F Would you say that instances of the class Rectangle2 are immutable objects? Part 1.G Write a mutable version of the class Rectangle2 called Rectangle3 by adding a setwidth(double width) and a segheight(double height) methods. These methods must throw an exception if asked to set an invalid width or height for the rectangle. Test your class with the following program: Rectangle3Test.java 1 class Rectangle3Test { 3 try { 4 Rectangle3 r = new Rectangle3(1D, 3D); 5 System.out.println(r); 6 r.setwidth(5d); 7 r.setheight(7d); 8 System.out.println(r); 9 r.setheight(-5d); 10 } catch (Exception ex) { 11 System.out.println(ex.getMessage()); 12 return; 13 } 14 } 15 } That must behave exactly as shown below: 1 $ java Rectangle2Test 2 Rectangle: width = 1.0 and height = 3.0 3 Rectangle: width = 5.0 and height = 7.0 4 ERROR: height must be > 0 2
Part 1.H Simplify the constructor of Rectangle3 by using the methods setwidth and setheight to make it look like this: public Rectangle3(double width, double height) throws exception { setwidth(width); setheight(height); } And explain if the class is still safe to use. Do you still need to declare that the constructor throws an exception, why? Which version of the constructor do you prefer? Part 1.I Create a new version of the class Rectangle3 called Rectangle4 that has two overloaded constructors: Rectangle4(double side) that creates a square rectangle of side side. an empty constructor that creates a square rectangle of side 1.0. Each of these two new constructors must also be safe and their bodies must have only one line of code. Part 1.J Create a new version of the class Rectangle4 called Rectangle5 that has: a method called area to calculate the area of the rectangle. a method called perimeter to calculate its perimeter. a method called invert that exchanges its width with its height. a method called equals to tell if another Rectangle5 has the same width and height than the one you are invoking this method on. Write the body of this method in only one line of code. a new overloaded constructor that receives a Rectangle5 and creates a new rectangle with the same width and height. This is called a clone constructor. Write the body of this constructor in only one line of code. Also write a test program for this class, testing all the new methods in imaginative ways (e.g. is the invert of the invert of a rectangle equals to a clone of the original?). Part 1.K Explain if Rectangle5.invert() can throw an exception. Are you sure? Part 1.L Explain why you can access the attributes of one Rectangle5 object from another Rectangle5 object if they are private (like you did in the equals method). 3
Exercise 2 Simulating Dice Part 2.A Write a class called SixSidedDie that simulates 6-sided die. It will have an empty constructor and a public int roll() method that returns a random integer between 1 and 6. Do not create a new random number generator for each roll; just create a new random number generator for each die. Tip: do you need to define an empty constructor for the class? or will the default constructor suffice. Part 2.B Write a program called SixSidedDieTest that test the class from the previous exercise by creating a die, rolling it 10 times and printing the outcomes. 1 $ java SixSidedDieTest 2 5 3 6 4 2 5 2 6 4 7 3 8 5 9 2 10 6 11 1 Part 2.C Write a class called Die that simulates dices of any number of sides. The constructor must throw an exception if the number of sides is smaller than 2 (this number, 2, is a magic number, avoid using it directly). Add also an empty constructor that construct dices of 6 sides. Part 2.D Write 3 or 4 paragraphs about how would you test the class from the previous exercise. Part 2.E Use the following program to test your Die class. Do you understand this program? 4
1 class DieTest { 2 final static private int NUM_ROLLS = 5; 3 DieTest.java 4 private static void test(int sides) { 5 try { 6 System.out.println("Rolling a dice of " + sides + 7 " sides " + NUM_ROLLS + " times in a row:"); 8 Die die = new Die(sides); 9 for (int i=0; i<num_rolls; i++) { 10 System.out.println(die.roll()); 11 } 12 } catch (Exception ex) { 13 System.err.println(ex); 14 } 15 } 16 17 public static void main(string args[]) { 18 test(-3); 19 test(1); 20 test(2); 21 test(6); 22 test(1000); 23 } 24 } Part 2.F Add a method called howmany to your Die class that returns the number of dice created so far. Test the class with the following program: CountDice.java 1 class CountDice { 3 try { 4 System.out.println(Die.howMany()); 5 Die d = new Die(); 6 d = new Die(); 7 d = new Die(); 8 System.out.println(Die.howMany()); 9 d = new Die(); 10 System.out.println(Die.howMany()); 11 } catch (Exception ex) { 12 System.err.println(ex); 13 } 14 } 15 } The output from the program should be exactly this: 1 $ java CountDice 2 0 3 3 4 4 5
Part 2.G Playing with REGEXs Write a program called RollDice that adds the rolls from a set of dice according to the following simplified Dungeons & Dragons notation: 1d6 means roll one 6-sided die 3d8 means roll three 8-sided dice and sum their outcomes 1 $ java RollDice 1d6 2 5 3 $ java RollDice 3d8 4 13 5 $ java RollDice 1000d100 6 51249 7 $ java RollDice 8 ERROR: bad number of arguments 9 $ java RollDice 1d6 3d6 10 ERROR: bad number of arguments 11 $ java RollDice alberto 12 ERROR: bad argument format 13 $ java RollDice 3d6a 14 ERROR: bad argument format 15 $ java RollDice 5d1 16 ERROR: number of sides must be >= 2 Tip: learn about regular expressions before trying to solve this problem. Exercise 3 Counting students is hard Part 3.A Write a Student class, that holds the information of a student: His name His surname His Student ID: a number different for each student, assigned to each student when he/she is created, starting from 1000. The tostring() method for this class must print the information for the student as shown below: surname, name (student_id) Test your class with a simple program that creates three students in this order: Alberto Cortés Beatriz González Carlos García Then print their info, first of Alberto, then Carlos, the Beatriz. The output from your program must look like this: 6
1 $ java StudentTest 2 Cortés, Alberto (1001) 3 García, Carlos (1003) 4 González, Beatriz (1002) Part 3.B Check the differences between your StrudentTest program and the teachers version and try to understand the differences if any: Teachers version of StudentTest.java 1 class StudentTest { 3 4 Student alberto = new Student("Alberto", "Cortés"); 5 Student beatriz = new Student("Beatriz", "Gonzalez"); 6 Student carlos = new Student("Carlos", "García"); 7 8 System.out.println(alberto); 9 System.out.println(carlos); 10 System.out.println(beatriz); 11 } 12 } 7