Object-Orientation & Inheritance
Table of Contents
1.
Session 6 (lab): Object-Orientation & Inheritance (III)
1.1. Points and Figures (II)
The general objective of this lab is to recap inheritance and
polymorphism in Java. You will be using abstract and
extends for inheritance, creating generic and especific
classes in a hierarchy. Especific classes will implement the
abstract methods defined in the generic ones and will override the
rest of their methods to implement polimorphism. The class hierarchy
in this lab is composed by the superclass Figure and
three of its clindrens: Circle, Triangle
and Quadrilateral. There is also a subclass of
Quadrilateral called Rectangle.
Once you have implemented all that classes, you will have to create a bunch of objects and insert them into a container. Then you will perform operations on all of them taking advantage of polimorphism.
The Figure class represents a generic figure, that
will later be particularized into a more concrete class like
Circle, Triangle or
Rectangle. In Java, this kind of generic, abstract
classes, are defined using the abstract reserved
word.
In this first exercise you must define the Figure
abstract class. You can download an initial templete for this
class from here.
public abstract class Figure {
// Name of the figure
private String name;
// Constructor of the figure
public Figure(String name) {
}
// Calculates the area of a figure
abstract public double area();
// Indicates if the figure is regular or not
abstract public boolean isRegular();
// Gets the name of the figure
protected String getName() {
}
// Sets the name of the figure
protected void setName(String name) {
}
}
Figure.
Program the constructor of the class Figure and
its get and set methods.
Circle.
The class Circle inherits from Figure,
take this into account when implementing it. Follow these steps:
Declare the class Circle inheriting from
Figure, using extends.
Implement its constructor. Said constructor must accept
three arguments: its name (String), its center
(Point) and its radius (int). Use
the class Point.java
to represent points, and call the constructor of the
Figure class through the super
reference on the Circle's constructor.
Program the method area that returns the area of
the circle. Use the constant Math.PI
in your calculations.
Program the method isRegular() that returns
true if the figure is regular or
false if it is not. Please note that circles
are always regular figures.
Override the method toString() to return a
textual representation of the name of the figure, its center
and its radius (the format of this textual representation is
up to you).
Program the get and set methods.
Triangle.
The class Triangle also inherits from
Figure. Follow these steps:
Declare the Triangle class to inherit from
Figure.
The constructor will receive four arguments: the name of the
class and three points (Point v1, Point
v2 and Point v3), representing the three
vertexes of the triangle. Remember you have to call the
constructor of Figure using super.
Program its area method. The area of a triangle
can be calculated form its vertexes usign the following
expresion: area =
0.5*|Ax(By-Cy)+Bx(Cy-Ay)+Cx(Ay-By)|, where
x is the abscissa and y the
ordinate of the correspoding vertexes (A, B, C). In the
expression, |...| represents the absolute value
of what is inside.
Program the method isRegular() to tell if the
triangle is regular. A triangle is regular if all its side
lenghts are equal.
Override the toString metod to return a
sensible textual representation of a triangle, including at
least its name and its vertexes.
Program the get and set methods.
Quadrilateral.
The Quadrilateral is another subclass of
Figure. But this time, we will make it also an
abstract class, because it is difficult to calculate its area
without knowing a little bit more about its details. Follow
these steps:
Declare an abstract class Quadrilateral that
inherits from Figure.
Implement its constructor, which receives five arguments: its name and four points.
Program the isRegular method to tell if the
figure is regular. Please note that a quadrilateral is
regular if it is also a rectangle. Use the method
checkRectangle at the end of this section to
help you program the isRegular method. How does
the checkRectangle method works?
Override the toString method to return a
sensible textual representation of a quadrilateral,
including its name and its vertexes.
Program the get and set methods.
/**
* Indicates if the quadrilateral is a rectangle or square by
* comparing sizes and diagonals.
*
*/
private boolean checkRectangle(Point v1, Point v2, Point v3, Point v4){
Point auxVertex = v1.nearest(new Point[]{v2,v3,v4});
if (auxVertex.equals(v2)){
return v1.distance(v3) == v2.distance(v4)
&& v1.distance(v4) == v2.distance(v3);
} else if (auxVertex.equals(v3)){
return v1.distance(v2) == v3.distance(v4)
&& v1.distance(v4) == v3.distance(v2);
} else if (auxVertex.equals(v4)){
return v1.distance(v2) == v4.distance(v3)
&& v1.distance(v3) == v4.distance(v2);
} else {
return false;
}
}
Rectangle.The subclass Rectangle inherits from
Quadrilateral. Follow these steps:
Declare the class Rectangle that inherits from
Quadrilateral.
Program its constructor, receiving 5 arguments, its name and
its 4 vertexes. Remember to call the constructor of the
Quadrilateral class through the
super reference. The constructor must check
that the four vertexes provided as its arguments are really
the vertexes of a rectangle, not just of a generic
quadrilateral. The constructor must throw an exception in
case the vertexes are wrong (you can read about exceptions
in this short
introduction to exceptions).
Program its area method. In a rectangle, given
a vertex, the distance to its two nearest vertexex, would be
the base and height of the rectangle.
Override the toString method to return a
sensible textual representation of a rectangle, including
its name and its vertexes. Can you reuse some code from the
Quadrilateral.toString method in here?
The class FiguresSet will contain several figures,
stored in an ArrayList<Figure> and will be
able to tell the total area of the figures it holds. Here is a
templete for this class:
import java.util.ArrayList;
public class FiguresSet {
// Array of figures
private ArrayList<Figure> figures;
// Constructor of FiguresSet
public FiguresSet() {
}
// Calculates the total area of the figures
public double totalArea() {
}
// figures to String
public String toString() {
}
// Adds a new figure to the FigureSet
public void addFigure(Figure f) {
}
// Main program
public static void main(String args[]) throws Exception {
}
}
The class constructor must create an object of the
ArrayList class to store the figures. Then the
user will be adding figures using the addFigure
method. The method totalArea can then be used to
get the total area of all the figures that have been added. The
toString method retuns a sensible textual
representation of all the figures included in the
FigureSet.
Implement the class constructor.
Write the addFigure method that allows to add
an Figure to the container.
Write the totalArea method that allows to
calculate the total area of the figures contained.
Write the toString method that returns a
sensible textual representation of all the figures inside.
main method.Create the main program that has to carry out the following tasks:
Create an object of the FiguresSet class.
Create a circle.
Create a triangle.
Create a rectangle.
Add the circle, the triangle and the rectangle to the FiguresSet object.
Print the result of the calculation of the total area of the figures along with the information about the figures.
public abstract class Figure {
// Name of the figure
private String name;
// Constructor of the figure with a name
public Figure (String name){
this.name = name;
}
// Calculates the area of a figure
public abstract double area();
// Indicates if the figure is regular or not
public abstract boolean isRegular();
// Gets the name of the figure
protected String getName(){
return this.name;
}
// Sets the name of the figure
protected void setName(String name){
this.name = name;
}
}
public class Point {
private double x;
private double y;
public Point(double x, double y) {
this.x = x;
this.y = y;
}
/**
* Returns the string representation of the point.
*
*/
public String toString() {
return "(" + x + ", " + y + ")";
}
/**
* Returns the distance to the origin.
*
*/
public double distance() {
Point origin = new Point(0.0, 0.0);
return distance(origin);
}
/**
* Returns the x coordinate of the point.
*
*/
public double getX() {
return x;
}
/**
* Returns the y coordinate of the point.
*
*/
public double getY() {
return y;
}
/**
* Returns the distance to another point.
*
*/
public double distance(Point anotherPoint) {
return Math.sqrt(Math.pow(x - anotherPoint.getX(), 2) +
Math.pow(y - anotherPoint.getY(), 2));
}
/**
* Returns the quadrant in which the point is.
*
*/
public int quadrant() {
if (x > 0.0 && y > 0.0) {
return 1;
} else if (x < 0.0 && y > 0.0) {
return 2;
} else if (x < 0.0 && y < 0.0) {
return 3;
} else if (x > 0.0 && y < 0.0) {
return 4;
} else {
// (x==0.0 || y==0.0)
return 0;
}
}
/**
* Returns the nearest point of the array in the parameter, or
* null if array is empty.
*
*/
public Point nearest(Point[] otherPoints) {
Point nearestPoint = null;
double minDistance = Double.MAX_VALUE;
double currentDistance;
for (int i=0; i<otherPoints.length; i++) {
currentDistance = this.distance(otherPoints[i]);
if (currentDistance <= minDistance) {
minDistance = currentDistance;
nearestPoint = otherPoints[i];
}
}
return nearestPoint;
}
}
public class Circle extends Figure {
public static final double PI = Math.PI;
private Point center;
private int radius;
// Constructor of the circle
public Circle (String name, Point center, int radius){
super(name);
this.center = center;
this.radius = radius;
}
// Calculates the area of the circle
public double area() {
return PI*radius*radius;
}
// The circle is always a regular figure
public boolean isRegular() {
return true;
}
// Circle to String
public String toString() {
return ("Circle: " + getName() + "; Radius: " + getRadius()
+ "; Center" + getCenter().toString());
}
// Gets the center of the circle
private Point getCenter(){
return this.center;
}
// Sets the center of the circle
private void setCenter(Point center){
this.center = center;
}
// Gets the radius of the circle
private int getRadius(){
return this.radius;
}
// Sets the radius of the circle
private void setRadius(int radius){
this.radius = radius;
}
}
public class Triangle extends Figure{
// Vertexes of the triangle
private Point vertex1;
private Point vertex2;
private Point vertex3;
// Constructor of the triangle
public Triangle(String name, Point vertex1, Point vertex2, Point vertex3) {
super(name);
this.vertex1 = vertex1;
this.vertex2 = vertex2;
this.vertex3 = vertex3;
}
// Calculates the area of the triangle
public double area() {
return 0.5 * Math.abs(vertex1.getX() * (vertex2.getY() - vertex3.getY())
+ vertex2.getX() * (vertex3.getY() - vertex1.getY())
+ vertex3.getX() * (vertex1.getY() - vertex2.getY()));
}
// Indicates if the triangle is regular (equilateral triangle) or not
public boolean isRegular(){
return (vertex1.distance(vertex2) == vertex2.distance(vertex3))
&& (vertex1.distance(vertex2) == vertex3.distance(vertex1));
}
// Triangle to String
public String toString() {
return ("Triangle: " + getName() + "; Vertexes: "
+ getVertex1().toString() + getVertex2().toString()
+ getVertex3().toString());
}
// Gets vertex1 of the triangle
private Point getVertex1() {
return vertex1;
}
// Gets vertex2 of the triangle
private Point getVertex2() {
return vertex2;
}
// Gets vertex3 of the triangle
private Point getVertex3() {
return vertex3;
}
// Sets vertex1 of the triangle
private void setVertex1(Point vertex1) {
this.vertex1 = vertex1;
}
// Sets vertex2 of the triangle
private void setVertex2(Point vertex2) {
this.vertex2 = vertex2;
}
// Sets vertex3 of the triangle
private void setVertex3(Point vertex3) {
this.vertex3 = vertex3;
}
}
public abstract class Quadrilateral extends Figure {
// Vertexes of the quadrilateral
private Point vertex1;
private Point vertex2;
private Point vertex3;
private Point vertex4;
// Constructor of the quadrilateral
public Quadrilateral(String name, Point vertex1, Point vertex2,
Point vertex3, Point vertex4) {
super(name);
this.vertex1 = vertex1;
this.vertex2 = vertex2;
this.vertex3 = vertex3;
this.vertex4 = vertex4;
}
// Calculates the area of the quadrilateral
public abstract double area();
// Indicates if the quadrilateral is regular.
public boolean isRegular(){
return checkRectangle(vertex1, vertex2, vertex3, vertex4);
}
/**
* Indicates if the quadrilateral is a rectangle or square by
* comparing sizes and diagonals.
*
*/
private boolean checkRectangle(Point v1, Point v2, Point v3, Point v4){
Point auxVertex = v1.nearest(new Point[]{v2,v3,v4});
if (auxVertex.equals(v2)){
return v1.distance(v3) == v2.distance(v4)
&& v1.distance(v4) == v2.distance(v3);
} else if (auxVertex.equals(v3)){
return v1.distance(v2) == v3.distance(v4)
&& v1.distance(v4) == v3.distance(v2);
} else if (auxVertex.equals(v4)){
return v1.distance(v2) == v4.distance(v3)
&& v1.distance(v3) == v4.distance(v2);
} else {
return false;
}
}
// Quadrilateral to String
public String toString(){
return (getName() + "; Vertexes: " + getVertex1().toString()
+ getVertex2().toString() + getVertex3().toString()
+ getVertex4().toString());
}
// Gets vertex1 of the quadrilateral
protected Point getVertex1(){
return vertex1;
}
// Gets vertex2 of the quadrilateral
protected Point getVertex2(){
return vertex2;
}
// Gets vertex3 of the quadrilateral
protected Point getVertex3(){
return vertex3;
}
// Gets vertex4 of the quadrilateral
protected Point getVertex4(){
return vertex4;
}
// Sets vertex1 of the quadrilateral
protected void setVertex1(Point vertex1){
this.vertex1 = vertex1;
}
// Sets vertex2 of the quadrilateral
protected void setVertex2(Point vertex2){
this.vertex2 = vertex2;
}
// Sets vertex3 of the quadrilateral
protected void setVertex3(Point vertex3){
this.vertex3 = vertex3;
}
// Sets vertex4 of the quadrilateral
protected void setVertex4(Point vertex4){
this.vertex4 = vertex4;
}
}
public class Rectangle extends Quadrilateral {
// Constructor of the rectangle
public Rectangle(String name, Point vertex1, Point vertex2, Point vertex3,
Point vertex4) throws BadFigureException {
super(name,vertex1,vertex2,vertex3,vertex4);
if (super.isRegular() == false){
throw new BadFigureException("The vertexes are incompatible with"
+ " a rectangle.");
}
}
// Calculates the area of the rectangle (base times the height)
public double area() {
Point[] vertices234 = new Point[] {getVertex2(), getVertex3(),
getVertex4()};
Point auxVertex = getVertex1().nearest(vertices234);
Point[] otherVertices = null;
if (auxVertex.equals(getVertex2())) {
otherVertices = new Point[] {getVertex3(), getVertex4()};
} else if (auxVertex.equals(getVertex3())) {
otherVertices = new Point[] {getVertex2(), getVertex4()};
} else if (auxVertex.equals(getVertex4())) {
otherVertices = new Point[] {getVertex2(), getVertex3()};
}
double base = getVertex1().distance(auxVertex);
double height = auxVertex.distance(auxVertex.nearest(otherVertices));
return base * height;
}
// Rectangle to String
public String toString() {
return ("Rectangle: " + super.toString());
}
}
import java.util.ArrayList;
public class FiguresSet {
// Array of figures
private ArrayList<Figure> figures;
// Constructor of FiguresSet
public FiguresSet() {
figures = new ArrayList<Figure>();
}
// Calculates the total area of the figures
public double totalArea() {
double totalArea = 0;
for (int i=0; i<figures.size(); i++){
totalArea = totalArea + figures.get(i).area();
}
return totalArea;
}
// figures to String
public String toString() {
String s = new String();
for (int i=0; i<figures.size(); i++){
s = s + figures.get(i).toString() + "\n";
}
return s;
}
// Adds a new figure to the FigureSet
public void addFigure(Figure f) {
figures.add(f);
}
// Main program
public static void main(String args[]) throws Exception {
FiguresSet figures = new FiguresSet();
Circle c = new Circle("Circle1", new Point(1, 1), 4);
Triangle t = new Triangle("Triangle1", new Point(1, 1),
new Point(3, 1), new Point(2, 3));
figures.addFigure(c);
figures.addFigure(t);
try {
Rectangle r = new Rectangle("Rectangle1", new Point(1, 4),
new Point(4, 1), new Point(1, 1),
new Point(4, 4));
figures.addFigure(r);
} catch (BadFigureException e) {
System.out.println("Error: " + e.getMessage());
}
System.out.println(figures.toString());
System.out.println("Total area: " + figures.totalArea());
}
}
2.
Homework
2.1. Using Interfaces to calculate PiInterfaces can be very useful for having several alternative implementations of the same functionality: we would like the main program to use one or the other without noticing the changes.
In this exercise we will have several implementations of a class that calculates the number pi. We will be using the following interface:
import java.math.BigDecimal;
/**
* Interface to be implemented by classes that compute the number pi.
*
*/
public interface PiProvider {
/**
* Computes and returns the value of the number pi. Implementations
* may decide the precision with which they compute the value.
*
* @return The number pi, with the precision each implementation
* decides.
*
*/
BigDecimal computePi();
}
As some implementations will be able to calculate pi with a desired
precision, we will define also the following interface, that
inherits from PiProvider and add some more methods to
deal with precisions.
import java.math.BigDecimal;
/**
* Interface to be implemented by classes that compute the number pi.
* Classes that implement this interface can provide the value of pi
* with the requested precision, understood as the number of exact
* digits of the computed value.
*
*/
public interface AdvancedPiProvider extends PiProvider {
/**
* Sets the desired precision.
*
* @param precision The desired precision (number of digits).
*
* @throws PrecisionException if the desired precision is
* negative, zero or bigger than the maximum precision
* this class can provide.
*
*/
void setPrecision(int precision) throws PrecisionException;
/**
* Returns the current value of precision.
*
* @return The current value of precision (number of digits).
*
*/
int getPrecision();
/**
* Returns the maximum precision with which this provider is able
* to generate the value of pi.
*
* @return The maximum precision available from this provider, or
* Integer.MAX_VALUE if the provider can provide an
* arbitrarily big precision.
*
*/
int getMaximumPrecision();
}
As you can see, the method setPrecision will throw an
exception if the desired precision is not a valid precision value
(less than 1 or greater than the maximum precision allowed by each
particular implementation). Here is the code of this exception:
public class PrecisionException extends Exception {
public PrecisionException(int precision) {
super("Unsupported precision: " + precision);
}
}
Program and test a class called PiSimple that
implements the PiProvider interface and returns the
value of pi as (simply) 3.14.
import java.math.BigDecimal;
public class PiSimple implements PiProvider {
public BigDecimal computePi() {
return new BigDecimal("3.14");
}
}
Program and test a class called PiFromMath that
implements the PiProvider interface and returns the
value of pi defined by Math.PI as a
BigDecimal.
import java.math.BigDecimal;
public class PiFromMath implements PiProvider {
public BigDecimal computePi() {
return new BigDecimal(Math.PI);
}
}
Program and test a class called PiFromBBP that
implements the AdvancedPiProvider interface, using
the code from the PiCalc class you wrote in a
previous lab. You will only need to make a few changes to adapt
it.
import java.math.BigDecimal;
import java.math.MathContext;
public class PiCalc {
private int numDigits;
private MathContext mc;
public PiCalc(int numDigits) {
this.numDigits = numDigits;
mc = new MathContext(numDigits);
}
public BigDecimal compute() {
BigDecimal pi = new BigDecimal(0);
BigDecimal limit = new BigDecimal(1).movePointLeft(numDigits);
boolean stop = false;
for (int k = 0; !stop; k++) {
BigDecimal piK = piFunction(k);
pi = pi.add(piK);
if (piK.compareTo(limit) < 0) {
stop = true;
}
}
return pi.round(mc);
}
private BigDecimal piFunction(int k) {
int k8 = 8 * k;
BigDecimal val1 = new BigDecimal(4);
val1 = val1.divide(new BigDecimal(k8 + 1), mc);
BigDecimal val2 = new BigDecimal(-2);
val2 = val2.divide(new BigDecimal(k8 + 4), mc);
BigDecimal val3 = new BigDecimal(-1);
val3 = val3.divide(new BigDecimal(k8 + 5), mc);
BigDecimal val4 = new BigDecimal(-1);
val4 = val4.divide(new BigDecimal(k8 + 6), mc);
BigDecimal val = val1;
val = val.add(val2);
val = val.add(val3);
val = val.add(val4);
BigDecimal multiplier = new BigDecimal(16);
multiplier = multiplier.pow(k);
BigDecimal one = new BigDecimal(1);
multiplier = one.divide(multiplier, mc);
val = val.multiply(multiplier);
return val;
}
public static void main(String[] args) {
if (args.length != 1) {
System.err.println("One command-line argument expected: number of "
+ "digits.");
} else {
PiCalc piCalc = new PiCalc(Integer.parseInt(args[0]));
System.out.println(piCalc.compute());
}
}
}
Please note that the new constructor will not receive any arguments, as the default desired precision will be 30 decimal places.
import java.math.BigDecimal;
import java.math.MathContext;
public class PiFromBBP implements AdvancedPiProvider {
private int numDigits;
private MathContext mc;
public PiFromBBP() {
setPrecisionInternal(30);
}
public void setPrecision(int numDigits) throws PrecisionException {
if (numDigits < 1) {
throw new PrecisionException(numDigits);
}
setPrecisionInternal(numDigits);
}
public int getPrecision() {
return numDigits;
}
public int getMaximumPrecision() {
return Integer.MAX_VALUE;
}
public BigDecimal computePi() {
BigDecimal pi = new BigDecimal(0);
BigDecimal limit = new BigDecimal(1).movePointLeft(numDigits);
boolean stop = false;
for (int k = 0; !stop; k++) {
BigDecimal piK = piFunction(k);
pi = pi.add(piK);
if (piK.compareTo(limit) < 0) {
stop = true;
}
}
return pi.round(mc);
}
private void setPrecisionInternal(int numDigits) {
this.numDigits = numDigits;
mc = new MathContext(numDigits);
}
private BigDecimal piFunction(int k) {
int k8 = 8 * k;
BigDecimal val1 = new BigDecimal(4);
val1 = val1.divide(new BigDecimal(k8 + 1), mc);
BigDecimal val2 = new BigDecimal(-2);
val2 = val2.divide(new BigDecimal(k8 + 4), mc);
BigDecimal val3 = new BigDecimal(-1);
val3 = val3.divide(new BigDecimal(k8 + 5), mc);
BigDecimal val4 = new BigDecimal(-1);
val4 = val4.divide(new BigDecimal(k8 + 6), mc);
BigDecimal val = val1;
val = val.add(val2);
val = val.add(val3);
val = val.add(val4);
BigDecimal multiplier = new BigDecimal(16);
multiplier = multiplier.pow(k);
BigDecimal one = new BigDecimal(1);
multiplier = one.divide(multiplier, mc);
val = val.multiply(multiplier);
return val;
}
}
Program and test a class called PiStored that stores
a precalculated value of pi as an String. When asked
for a new value of pi, it will return the corresponding stored
value (using the desired precision). The maximum precision will be
limited by the size of the stored string.
Its constructor must not receive any parameters. The default precision will be 30 decimal places.
You can use the following string as the value of pi:
private static final String PI = "3.14159265358979323846264338327950"
+ "2884197169399375105820974944592307"
+ "8164062862089986280348253421170679";
To copy a piece of the string, you can use the method substring from the class
String.
import java.math.BigDecimal;
public class PiStored implements AdvancedPiProvider {
private int numDigits;
private static final String PI = "3.14159265358979323846264338327950"
+ "2884197169399375105820974944592307"
+ "8164062862089986280348253421170679";
public PiStored() {
setPrecisionInternal(getMaximumPrecision());
}
public void setPrecision(int numDigits) throws PrecisionException {
if (numDigits < 1 || numDigits > getMaximumPrecision()) {
throw new PrecisionException(numDigits);
}
setPrecisionInternal(numDigits);
}
public int getPrecision() {
return numDigits;
}
public int getMaximumPrecision() {
return PI.length() - 1;
}
public BigDecimal computePi() {
int length;
if (numDigits == 1) {
length = 1;
} else {
length = 1 + numDigits;
}
BigDecimal pi = new BigDecimal(PI.substring(0, length));
return pi;
}
private void setPrecisionInternal(int numDigits) {
this.numDigits = numDigits;
}
}
Program and test a class called Circle that:
BigDecimal.
area that receives an object
implementing the PiProvider interface and returns
the area of the circle calculated using the value of pi supplied
by that object.
You must carefully make use of polymorphism so this class can use
any implementation of the PiProvider interface. This
means also to foresee new implementations, different from the ones
you made yourself. Test your code using different instances of
each of your interface implementations.
import java.math.BigDecimal;
public class Circle {
private BigDecimal radius;
public Circle(BigDecimal radius) {
this.radius = radius;
}
public BigDecimal area(PiProvider piProvider) {
return radius.multiply(radius).multiply(piProvider.computePi());
}
}
import java.math.BigDecimal;
public class TestPi {
public static void main(String[] args) throws PrecisionException {
PiProvider piSimple = new PiSimple();
System.out.println("Pi simple:\t"
+ piSimple.computePi());
PiProvider piFromMath = new PiFromMath();
System.out.println("Pi from math:\t" + piFromMath.computePi());
AdvancedPiProvider piFromBBP = new PiFromBBP();
piFromBBP.setPrecision(40);
if (piFromBBP.getPrecision() != 40) {
System.out.println("Wrong precision in PiFromBBP");
}
System.out.println("Pi from BBP:\t" + piFromBBP.computePi());
AdvancedPiProvider piStored = new PiStored();
piStored.setPrecision(40);
if (piStored.getPrecision() != 40) {
System.out.println("Wrong precision in PiStored");
}
System.out.println("Pi stored:\t" + piStored.computePi());
Circle circle = new Circle(new BigDecimal(2));
System.out.println("\nArea simple:\t" + circle.area(piSimple));
System.out.println("Area from math:\t" + circle.area(piFromMath));
System.out.println("Area from BBP:\t" + circle.area(piFromBBP));
System.out.println("Area stored:\t" + circle.area(piStored));
}
}