Identifying actions to create methods
So far, we designed nine classes and identified the necessary fields for each of them. Now, it is time to add the necessary pieces of code that work with the previously defined fields to perform all the necessary tasks, that is, to calculate perimeters and areas. We have to make sure that each class has the necessary encapsulated functions that process the property values specified in the objects to perform all the tasks.
Let's forget a bit about similarities between the different classes. We will work with them inpidually as if we didn't have the necessary knowledge of geometric formulas. We will start with the Circle
class. We need pieces of code that allow each instance of this class to use the value of the radius
property to calculate the area and perimeter.
Tip
The functions defined in a class to encapsulate the behavior of each instance of the class are known as methods. Each instance can access the set of methods exposed by the class. The code specified in a method can work with the fields specified in the class. When we execute a method, it will use the fields of the specific instance. Whenever we define methods, we must make sure that we define them in a logical place, that is, in the place where the required data is kept.
When a method doesn't require parameters, we can say that it is a parameterless method. In this case, all the methods we will initially define for the classes will be parameterless methods that just work with the values of the previously defined fields and use the formulas previously shown in the figures when we analyzed each 2D shape in detail. Thus, we will be able to call these methods without arguments. We will start creating methods, but we will be able to explore additional options based on specific Java 9 features later.
The Circle
class defines the following two parameterless methods. We will declare the code for both methods within the definition of the Circle
class so that they can access the radius
property value, as follows:
calculateArea
: This method returns a floating point value with the calculated area for the circle. It returns Pi (π
) multiplied by the square of theradius
field value (π * radius2 or π * (radius ^ 2)).calculatePerimeter
: This method returns a floating point value with the calculated perimeter for the circle. It returns Pi (π
) multiplied by 2 times theradius
field value (π * 2 * radius).
Tip
In Java 9, Math.PI
provides us with the value for Pi. The Math.pow
method allows us to calculate the value of a first argument raised to the power of the second argument. We will learn how to code these methods in Java 9 later.
These methods do not have side effects, that is, they do not make changes to the related instance. The methods just return the calculated values, and therefore, we consider them non-mutating methods. Their operation is naturally described by the calculate
verb.
Java 9 uses a dot (.
) to allow us to execute the methods of the instances. Imagine that we have two instances of the Circle
class: circle1
with the radius
property equal to 5
and circle2
with the radius
property equal to 10
.
If we call circle1.calculateArea()
, it will return the result of π * 52, which is approximately 78.54
. If we call square2.calculateArea()
, it will return the result of π * 102, which is approximately 314.16
. Each instance has a perse value for the radius
attribute, and therefore, the results of executing the calculateArea
method are different for each of them.
If we call circle1.calculatePerimeter()
, it will return the result of π * 2 * 5, which is approximately 31.41
. On the other hand, if we call circle2.calculatePerimeter()
, it will return the result of π *2 * 10, which is approximately 62.83
.
Now, let's move to the Rectangle
class. We need exactly two methods with the same names specified for the Circle
class: calculateArea
and calculatePerimeter
. In addition, the methods return the same type and don't need parameters, so we can declare both of them as parameterless methods, as we did in the Circle
class. However, these methods have to calculate the results in a different way; that is, they have to use the appropriate formulas for a rectangle and take into account the values for the width
and height
fields. The other classes also need the same two methods. However, each of them will use the appropriate formulas for the related shape.
We have a specific problem with the calculatePerimeter
method that the Ellipse
class generates. Perimeters are extremely complex to calculate for ellipses, so there are many formulas that provide approximations. An exact formula requires an infinite series of calculations. We will use an initial formula that isn't very accurate but we will find a workaround for this situation later and we will improve the results. The initial formula will allow us to return a floating point value with the calculated approximation of the perimeter for the ellipse.
The following diagram shows an updated version of the UML diagram with the nine classes, their attributes, and their methods. It shows the results of the second round: