More on Object Oriented Programming
Seoul National University of Science and Technology
Information Technology Management
Lecture slides index
May 19, 2025
hours: minutes: seconds
, where two digits are used to represent the hour (e.g., 01 or 12) as well as the minutes and seconds.int hours = 0;
int minutes = 0;
int seconds = 0;
while (true) {
// 1. Printing the time
if (hours < 10) {
System.out.print("0");
}
System.out.print(hours);
System.out.print(":");
if (minutes < 10) {
System.out.print("0");
}
System.out.print(minutes);
System.out.print(":");
if (seconds < 10) {
System.out.print("0");
}
System.out.print(seconds);
System.out.println();
// 2. The second hand's progress
seconds = seconds + 1;
// 3. The other hand's progress when necessary
if (seconds > 59) {
minutes = minutes + 1;
seconds = 0;
if (minutes > 59) {
hours = hours + 1;
minutes = 0;
if (hours > 23) {
hours = 0;
}
}
}
}
As we can see by reading the previous example, how a clock consisting of three int
variables works is not clear to someone reading the code.
By looking at the code, it’s difficult to “see” what’s going on.
A famous programmer once remarked
“Any fool can write code that a computer can understand .Good Programmers write code that humans can understand”.
Our aim is to make the program more understandable.
Since a clock hand is a clear concept in its own right, a good way to improve the program’s clarity would be to turn it into a class.
Let’s create a ClockHand
class that describes a clock hand, which contains information about its value, upper limit (i.e., the point at which the value of the hand returns to zero), and provides methods for advancing the hand, viewing its value, and also printing the value in string form.
ClockHand
class implementationpublic class ClockHand {
private int value;
private int limit;
public ClockHand(int limit) {
this.limit = limit;
this.value = 0;
}
public void advance() {
this.value = this.value + 1;
if (this.value >= this.limit) {
this.value = 0;
}
}
public int value() {
return this.value;
}
public String toString() {
if (this.value < 10) {
return "0" + this.value;
}
return "" + this.value;
}
}
ClockHand
classClockHand
class, our clock has become clearer.ClockHand
class.ClockHand hours = new ClockHand(24);
ClockHand minutes = new ClockHand(60);
ClockHand seconds = new ClockHand(60);
while (true) {
// 1. Printing the time
System.out.println(hours + ":" + minutes + ":" + seconds);
// 2. Advancing the second hand
seconds.advance();
// 3. Advancing the other hands when required
if (seconds.value() == 0) {
minutes.advance();
if (minutes.value() == 0) {
hours.advance();
}
}
}
ClockHand
class, the way the hands work together is slightly different than in the implementation that used integers.int
variables.advance()
.CounterLimitedFromTop
, for instance.public class Clock {
private ClockHand hours;
private ClockHand minutes;
private ClockHand seconds;
public Clock() {
this.hours = new ClockHand(24);
this.minutes = new ClockHand(60);
this.seconds = new ClockHand(60);
}
public void advance() {
this.seconds.advance();
if (this.seconds.value() == 0) {
this.minutes.advance();
if (this.minutes.value() == 0) {
this.hours.advance();
}
}
}
public String toString() {
return hours + ":" + minutes + ":" + seconds;
}
}
Clock
that hides the hands inside of it.Clock
classClockHand
class described above.Timer
class based on the material’s Clock
class.public Timer()
creates a new timer.public String toString()
returns a string representation of the timer. The string representation should be in the form “seconds: hundredths of a second”, where both the seconds and the hundredths of a second are represented by two numbers. For example, “19:83” would represent the time 19 seconds, 83 hundredths of a second.public void advance()
moves the timer forward by a hundredth of a second.
public class ClockHand {
private int value;
private int limit;
public ClockHand(int limit) {
this.limit = limit;
this.value = 0;
}
public void advance() {
this.value = this.value + 1;
if (this.value >= this.limit) {
this.value = 0;
}
}
public int value() {
return this.value;
}
public String toString() {
if (this.value < 10) {
return "0" + this.value;
}
return "" + this.value;
}
}
Timer timer = new Timer();
while (true) {
System.out.println(timer);
timer.advance();
try {
Thread.sleep(10);
} catch (Exception e) {
}
}
Caution
An Object refers to an independent entity that contains both data (instance variables) and behavior (methods).
Objects may come in lots of different forms: some may describe problem-domain concepts, others are used to coordinate the interaction that happens between objects.
Objects interact with one another through method calls – these method calls are used to both request information from objects and give instructions to them.
Generally, each object has clearly defined boundaries and behaviors and is only aware of the objects that it needs to perform its task.
In other words, the object hides its internal operations, providing access to its functionality through clearly defined methods.
Moreover, the object is independent of any other object that it doesn’t require to accomplish its task.
Person
class.Person
object that keeps track of name, age, weight, and height, and provides the ability to calculate body mass index and maximum heart rate would look like the following.public class Person {
private String name;
private int age;
private double weight;
private double height;
public Person(String name, int age, double weight, double height) {
this.name = name;
this.age = age;
this.weight = weight;
this.height = height;
}
public double bodyMassIndex() {
return this.weight / (this.height * this.height);
}
public double maximumHeartRate() {
return 206.3 - (0.711 * this.age);
}
public String toString() {
return this.name + ", BMI: " + this.bodyMassIndex()
+ ", maximum heart rate: " + this.maximumHeartRate();
}
}
Scanner reader = new Scanner(System.in);
System.out.println("What's your name?");
String name = reader.nextLine();
System.out.println("What's your age?");
int age = Integer.valueOf(reader.nextLine());
System.out.println("What's your weight?");
double weight = Double.valueOf(reader.nextLine());
System.out.println("What's your height?");
double height = Double.valueOf(reader.nextLine());
Person person = new Person(name, age, weight, height);
System.out.println(person);
// class
public class Rectangle {
// instance variables
private int width;
private int height;
// constructor
public Rectangle(int width, int height) {
this.width = width;
this.height = height;
}
// methods
public void widen() {
this.width = this.width + 1;
}
public void narrow() {
if (this.width > 0) {
this.width = this.width - 1;
}
}
public int surfaceArea() {
return this.width * this.height;
}
public String toString() {
return "(" + this.width + ", " + this.height + ")";
}
}
void
in their definition), while others do (methods that specify the type of variable to be returned).toString
method, which returns the string used to print the object.new
command.Create a Book
class that describes a book.
Each book has an author, title, and page count.
Make the class a:
Constructor public Book(String author, String name, int pages)
Method public String getAuthor()
that returns the book’s author’s name.
Method public String getName()
that returns the name of the book.
Method public int getPages()
that returns the number of pages in the book.
In addition, make a public String toString()
method for the book that will be used to print the book object.
For example, the method call should produce the following output:
Create a Cube
class that represents a cube (i.e., a standard hexahedron).
Create a public Cube (int edgeLength)
constructor for the class, that takes the length of the cube’s edge as its parameter.
Make a public int volume()
method for the cube, which calculates and returns the cube’s volume.
edgeLength * edgeLength * edgeLength
.Moreover, make a public String toString()
method for the cube, which returns a string representation of it.
The string representation should take the form “The length of the edge is l and the volume v
”, where l
is the length and v
the volume - both the length and volume must be represented as integers.
Examples are provided below
The Karvonen method allows you to calculate your target heart rate for physical exercise.
The target heart rate is calculated with the formula (maximum heart rate - resting heart rate) * (target heart rate percentage) + resting heart rate
, where the target heart rate is given as a percentage of the maximum heart rate.
For example, if a person has a maximum heart rate of 200
, a resting heart rate of 50
, and a target heart rate of 75%
of the maximum heart rate, the target heart rate should be about ((200-50) * (0.75) + 50)
, i.e., 162.5
beats per minute.
Create a class called Fitbyte
.
Its constructor takes both an age and a resting heart rate as its parameters.
The exercise should provide a method targetHeartRate
, which is passed a number of type double as a parameter that represents a percentual portion of the maximum heart rate.
The class should have:
public Fitbyte(int age, int restingHeartRate)
public double targetHeartRate(double percentageOfMaximum)
that calculates and returns the target heart rate.Use the 206.3 - (0.711 * age)
formula to calculate the maximum heart rate.
Person
classpublic class Person {
private String name;
private int age;
private int height;
private int weight;
public Person(String name) {
this.name = name;
this.age = 0;
this.weight = 0;
this.height = 0;
}
public void printPerson() {
System.out.println(this.name + " is " + this.age + " years old");
}
public void growOlder() {
this.age++;
}
public boolean isAdult() {
if (this.age < 18) {
return false;
}
return true;
}
public double bodyMassIndex() {
double heightInMeters = this.height / 100.0;
return this.weight / (heightInMeters * heightInMeters);
}
public String toString() {
return this.name + " is " + this.age + " years old, their BMI is " + this.bodyMassIndex();
}
public void setHeight(int height) {
this.height = height;
}
public int getHeight() {
return this.height;
}
public int getWeight() {
return this.weight;
}
public void setWeight(int weight) {
this.weight = weight;
}
public String getName() {
return this.name;
}
}
We would also like to be able to create persons so that the constructor is provided both the age as well as the name as parameters.
This is possible since a class may have multiple constructors.
Let’s make an alternative constructor.
The old constructor can remain in place.
public Person(String name, int weight)
constructor since it would be impossible for Java to differentiate between this and the one that has two parameters where int
parameter is used for age.this
keyword, which refers to this object in question!public Person(String name) {
this(name, 0);
//here the code of the second constructor is run, and the age is set to 0
}
public Person(String name, int age) {
this.name = name;
this.age = age;
this.weight = 0;
this.height = 0;
}
this(name, 0);
might seem a bit weird.Important
If a constructor calls another constructor, the constructor call must be the first command in the constructor.
public static void main(String[] args) {
Person paul = new Person("Paul", 24);
Person eve = new Person("Eve");
System.out.println(paul);
System.out.println(eve);
}
Product
, which represents a product in a shop.Product
class:
public Product(String name)
creates a product with the given name.
public Product(String name, String location)
creates a product with the given name and the given location.
public Product(String name, int weight)
creates a product with the given name and the given weight.
public class Product {
private String name;
private String location;
private int weight;
public Product(String name, String location, int weight) {
this.name = name;
this.location = location;
this.weight = weight;
}
public String getName() {
return name;
}
public int getWeight() {
return weight;
}
public String getLocation() {
return location;
}
@Override
public String toString() {
return this.name + " (" + this.weight + " kg) can be found from the " + this.location;
}
}
growOlder
method that ages the person by the amount of years given to it as a parameter.growOlder
.growOlder(int years)
:Counter
.public Counter(int startValue)
sets the start value of the counter to startValue.public Counter()
sets the start value of the counter to 0.public int value()
returns the current value of the counterpublic void increase()
increases the value by 1public void decrease()
decreases the value by 1increase
and decrease
.
public void increase(int increaseBy)
increases the value of the counter by the value of increaseBy.
public void decrease(int decreaseBy)
decreases the value of the counter by the value of decreaseBy.
Computer Language