0% found this document useful (0 votes)
18 views

Lab 2

Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
18 views

Lab 2

Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 6

TOPICS

• More on Java basic syntax (data types and


control structures)
• Object-oriented programming basics
• Calling methods within the same class,
from a different class, and from a different
package
• Private vs. public and the motivation
behind information hiding
• Static vs. non-static

Image source: https://www.jrebel.com/blog/top-java-development-tools-


and-software Dr. Rasha Alkhansa
CSC245B – Objects and Data Abstraction
CSC245B LAB 2
Fall 2024

Page 0 of 5
PROBLEM 1 – MYMATH

Java’s Math class provides several mathematical constants and methods such as Math.PI, Math.max and Math.sqrt.
In this exercise, you will develop your own version of the Math class, which you will call MyMath. A skeleton code is
provided to you in the file MyMath.java. The skeleton is also shown below. You need to complete the missing codes
(in the place of the 4 TODO items), as detailed below. This requires that you first read and understand the existing
codes with the help of the lab instructor.

(a) Define and implement the min and max methods which are called in the main method, as shown in the skeleton.
(b) Define the sqrt method which is also called in main, and implement it using the bisection method.
(c) Update the test code in main, by adding the following tests (sample run of the updated test is shown on the next
page):
• Ask the user to enter an integer, read this integer, then pass it to the abs method and display the result.
Note: although the abs method expects a double argument, you can pass an integer (e.g., 2) to it and Java
will automatically convert it to double (2.0).
• Add more test cases for the sqrt method. To this end, you need to loop over all test cases 𝑥 in [0,20], and for
each compute and display both sqrt(𝑥) and Math.sqrt(𝑥). The tests should show that your sqrt method is
obtaining equal (or at least very close) results to those obtained by Java’s Math.sqrt.
(d) Copy the entire test code (the main method) to a difference class: call it MyMathTest.java. What do you
notice? Make the necessary changes to the code in MyMathTest.java so that it works and obtains the same
results obtained by the test in MyMath.java.
(e) Now copy the entire MyMathTest.java class to another package. What change(s) should be done to the code to
allow this class to use the MyMath methods knowing that the MyMath class is defined in a different package?
Make these changes and test the code.

public class MyMath {


public static final double PI = 3.14159265;
//TODO define and implement the min method
//TODO define and implement the max method
//TODO define the sqrt method and implement it using the bisection method
// Returns the power of a number raised to the specified exponent
public static double pow(double base, int exponent) {
if (exponent == 0) {
return 1.0;
}
double result = 1.0;
for (int i = 0; i < abs(exponent); i++) { result *= base;}
return exponent < 0 ? 1.0 / result : result;
//equivalently: if (exponent<0) return 1.0/result; else return result;
}
// Returns the absolute value of a number
public static double abs(double a) {
return a < 0.0 ? -a : a;
}
// Example usage in a main method
public static void main(String[] args) {
int num1 = 10;
int num2 = 5;
System.out.println("Max of " + num1 + " and " + num2 + ": " + max(num1, num2));
System.out.println("Min of " + num1 + " and " + num2 + ": " + min(num1, num2));
double squareRootResult = sqrt(25.0);
System.out.println("Square root of 25: " + squareRootResult);
double powerResult = pow(2.0, 3);
System.out.println("2^3: " + powerResult);
double absoluteValueResult = abs(-15.0);
System.out.println("Absolute value of -15.0: " + absoluteValueResult);
//TODO read integer from user and display its absolute value using the abs method
//TODO add loop for more sqrt tests
}
}
Sample run:

Max of 10 and 5: 10
Min of 10 and 5: 5
Square root of 25: 5.0
2^3: 8.0
Absolute value of -15.0: 15.0

Enter an integer: -2
Absolute value of -2 is 2.0

sqrt(0) = 0.0
Math.sqrt(0) = 0.0
sqrt(1) = 1.0
Math.sqrt(1) = 1.0
sqrt(2) = 1.414213562373095
Math.sqrt(2) = 1.4142135623730951
sqrt(3) = 1.7320508075688772
Math.sqrt(3) = 1.7320508075688772
sqrt(4) = 2.0
Math.sqrt(4) = 2.0
sqrt(5) = 2.23606797749979
Math.sqrt(5) = 2.23606797749979
sqrt(6) = 2.449489742783178
Math.sqrt(6) = 2.449489742783178
sqrt(7) = 2.6457513110645907
Math.sqrt(7) = 2.6457513110645907
sqrt(8) = 2.82842712474619
Math.sqrt(8) = 2.8284271247461903
sqrt(9) = 3.0
Math.sqrt(9) = 3.0
sqrt(10) = 3.162277660168379
Math.sqrt(10) = 3.1622776601683795
sqrt(11) = 3.3166247903554
Math.sqrt(11) = 3.3166247903554
sqrt(12) = 3.4641016151377544
Math.sqrt(12) = 3.4641016151377544
sqrt(13) = 3.6055512754639896
Math.sqrt(13) = 3.605551275463989
sqrt(14) = 3.7416573867739418
Math.sqrt(14) = 3.7416573867739413
sqrt(15) = 3.872983346207417
Math.sqrt(15) = 3.872983346207417
sqrt(16) = 4.0
Math.sqrt(16) = 4.0
sqrt(17) = 4.123105625617661
Math.sqrt(17) = 4.123105625617661
sqrt(18) = 4.242640687119286
Math.sqrt(18) = 4.242640687119285
sqrt(19) = 4.358898943540673
Math.sqrt(19) = 4.358898943540674
sqrt(20) = 4.47213595499958
Math.sqrt(20) = 4.47213595499958
PROBLEM 2 – THE BOOK CLASS

Java provides eight primitive types (e.g., int, double, char, boolean, etc.) in addition to reference types (i.e., class
types, e.g., String). In this problem, you will see an example of a class definition and how it is used. Similar to the
String type, we will create a Book type allowing us to create instances of type Book and invoke methods related to
this type. The UML diagram below summarizes the Book type definition. It shows that each Book object has three
attributes: title and author of type String, and publicationYear of type int. The UML also shows the constructor and
methods defined for this type. The corresponding Java code is given in Book.java, and the test code using this
newly defined type is given in BookTest.java. The code in these two files is also shown on the next page.

Book
- title: String
- author: String
- publicationYear: int

+ Book (String, String, int)


+ getTitle( ) : String
+ getAuthor( ): String
+ getPublicationYear( ): int
+ setTitle(String)
+ setAuthor(String)
+ setPublicationYear(int)
+ displayBookInfo()

(a) Read the code (with the comments), run the test in main (in BookTest.java), and try to understand the
implementation and the displayed output.

(b) Add a one-argument constructor to the Book class. This constructor takes a String value and uses it to
initialize the title of the Book instance being created. On the other hand, the constructor initializes author to
“unknown” and the publicationYear to the default value of 1900.

(c) Implement the setPublicationYear method, where you need to validate that the year passed as argument is
in the range [1900-2023]; if the given year is valid, use it to set the publicationYear attribute of the instance;
otherwise, ignore the invalid value and set publicationYear to 1900. Notice that the publicationYear attribute
is private in the Book class, so it is not directly accessible to methods outside this class. Thus, instead of
being able to directly set a value to this attribute (e.g., myBook.publicationYear = 2000), the user is obliged
to use the public setter method, which guarantees that the given year value will be validated. Being able to
validate user-given arguments is one advantage of this information-hiding design approach (i.e., an
advantage of making the class attributes private).

(d) In the given main method, create 2 more book instances of your choice using the three-arguments and the
one-argument constructors, respectively.

(e) Also, in main, and using the getter methods, print book1's title and book2's author
Additional things to try: try to print them first without using the getters, i.e., by accessing the attributes
directly; what do you notice? Then in Book.java, change the visibility of the attributes to public instead of
private; go back to main, what do you notice now? After making your observations, make the attributes private
again.

(f) Now, using the setter methods, change book2's title to "Pity the Nation, new Edition" and its publication
year to 2002. Then display the updated info.
Additional things to try: try setting to an invalid year value before setting to 2002, and observe the results
(g) Add the following whoIsThis method to the Book class, then test it in BookTest. In your test, invoke this
method using the instance book1, and pass book2 as an argument. Try to predict the result of this test
before you hit run. After running the test, make sure you understand the displayed results; most
importantly, make sure to understand what this refers to in Java.

public void whoIsThis(Book arg) {


Book local = new Book("local book","",1990);
System.out.println(arg.getTitle());
System.out.println(this.getTitle());
System.out.println(getTitle());
System.out.println(local.getTitle());
}

Book.java:

public class Book {


// Attributes
private String title;
private String author;
private int publicationYear;

// Constructor
// A constructor is a special method which is called when a new Book object is
instantiated. It initializes the attributes of the object from the set of arguments.
public Book(String title, String author, int publicationYear) {
this.title = title;
this.author = author;
this.publicationYear = publicationYear;
}
//TODO add the one-argument constructor here

//Getter methods
public String getTitle() {return title; /*equivalent to return this.title;*/ }
public String getAuthor() {return author;}
public int getPublicationYear() {return publicationYear;}

//Setter methods
public void setTitle(String title) {this.title = title;}
public void setAuthor(String author) {this.author = author;}
public void setPublicationYear(int publicationYear) {
//TODO validate then set
}

// Method to display information about the book


public void displayBookInfo() {
System.out.println("Title: " + title);
System.out.println("Author: " + author);
System.out.println("Publication Year: " + publicationYear);
}
//TODO add the given whoIsThis method here
}
BookTest.java

public class BookTest {


public static void main(String[] args) {
//Create Book objects
Book book1 = new Book("Mornings in Jenin", "Suzan Abulhawa", 2010);
Book book2 = new Book("Pity the Nation", "Robert Fisk", 1990);

book1.displayBookInfo(); //display book1 info

//TODO create 2 more book instances of your choice using the 3-args
and the 1-arg constructors, respectively and display their info
//TODO print book1's title and book2's author
//TODO change book2's title to "Pity the
Nation, new Edition" and its publication year to 2002, then print
//TODO add the given whoIsThis test here
}
}

NOTES ON THE STATIC AND FINAL MODIFIERS

Notice that all the methods in MyMath (Problem 1) are defined as static methods, whereas those in the Book class
(Problem 2) are non-static. In general, the same class could include both static and non-static members. The main
difference between static and non-static methods is their dependence on the exitance of an instance (i.e., object) of
the class:

• Non-static methods (a.k.a. instance methods) should be invoked through an instance of the class. For
example, we need to create some Book instance (say book1) before we can call instance methods like
getTitle: book1.getTitle(). This method returns the title specific to the instance book1.
• Static methods can be called directly using the class name. For example, there is no need to create an
instance math1 of type MyMath to call the sqrt method.

Similarly, static class fields are fields (i.e., attributes) of the class (not specific to particular instances):

• The fields title, author, and publicationYear in the Book class are non-static, meaning that they depend on
the existence of Book objects (a title is specific to a certain book, and each book has a different title)
• In MyMath, the field PI is static and is thus independent of class instances (PI is the same for any instance of
type MyMath, and actually it does not even need an instance to exist: we can access this field directly using
the class name: MyMath.PI). Assume we have two MyMath instances: math1 and math2; since PI is static:
math1.PI, math2.PI and MyMath.PI all refer to the exact same field (stored in the same memory location). In
fact, a warning will be displayed if you access a static field/method using an instance name because the
instance is irrelevant (misleading to write math1.PI and better to write MyMath.PI). PI is also declared as a
final field to ensure that PI is constant. Since this field is declared final, any attempt to change its value
(using the class name or any instance name) will result in a compilation error.

In Java, when an attribute name is used, or a method is called without being preceded with an instance name or a
class name, Java implicitly inserts this for the non-static methods/fields and the enclosing class name for the static
ones.

Examples:

• In the WhoIsThis method, getTitle(), is equivalent to this.getTitle()


• In the main method of MyMath, sqrt(x) is equivalent to MyMath.sqrt(x)

More examples and illustrations will be given in the following labs.

You might also like