Table of Contents
The main objective of this exercise is to review the use of inheritance in Java and its application to arrays of objects. Inheritance is based on the use of abstract
and extends
reserved identifiers. We will write a generic class and several specific subclasses that derive from the first. All abstract methods will be implemented and other methods will be overridden to show the use of polymorphism when working with objects from a class hierarchy. Finally, we will use an array of objects from the previous hierarchy that will allow us to practice with all inheritance concepts.
In this exercise, we will calculate the total area of a collection of figures that have been previously created. Starting from the class Triangle
, we will create a generic Figure
class that will allow us to make abstraction when working with any type of figures. Once the behaviour of the Figure
class has been defined, we will derive our Triangle
class from it and then we will adapt it in order that it can be considered as a Figure
. We will also create the Square
class that will inherit also from Figure
.
WARNING: the geometry of triangles and squares is a bit more complex to model of what may seem at a first look. If we try to solve them, you will loose most of the time dealing with such geometry problems, instead of the programming. Therefore, we are going to make two simplifications: one of them abou the area of the triangle and the other one about the shape of the squere. That is, this exercise is mathematically incorrect. Both simplifications will be explained in the corresponding section, but notice that in a real program, instead of an exercise like this one, you would need to use the right mathematics.
Once all figures are created, we will implement a class that contains an array of figures (for example, a triangle and a square) and then we will calculate the total area of them using class polymorphism to calculate the specific area of each one of them.
Figure
and Triangle
classesThe Figure
class represents a generic figure that will materialize later on a specific one (Triangle
, Square
, etc...). In Java, all this concept is represented by abstract classes that must be declared with the abstract
reserved keyword.
An abstract class is a class that declares one or more abstract methods whose implementation is done in the corresponding subclasses. Review the theory if you don't remember this concept.
The first task of the exercise is to define the following Figure
abstract class which represents a generic geometric figure:
public abstract class Figure { /** Name of the figure */ String name; /** Constructor of the figure with a name */ 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(); }
Start by downloading the following code
Figure.java
.
Notice that two methods have been declared as abstract, therefore they must be implemented in the corresponding subclasses.
Figure
class.Write the constructor of the class.
Does it make sense to implement the constructor of an abstract class? What for?
Triangle
.The Triangle
class now inherits from Figure
and you must modify it so that it reflects
such changes. To do so, start downloading the code listing of the Triangle
class from this link
Triangle.java
and make the following changes:
You will need to access the code of the Point
class to be able to compile the Triangle
class. You can download it from the following link Point.java
.
Declare the Triangle
class as follows:
public class Triangle extends Figure
Modify all constructors so that, at the first line of the code, all of them invoke to the base class constructor of
the Figure
class. This is made by using the reference super
.
Implement the following methods:
The area()
method that calculates the area of the triangle. The prototype
of the method is as follows:
public double area() { /* complete */ }
The triangle's area is calculated according to the following formula:
Area = ( base X height ) / 2
Use the distance(Point anotherPoint)
method, of the Point
class, with the vertexes of the triangle.
To calculate the height of any triangle it is necessary to apply some trigonometry: assume that the triangle is isosceles or equilateral and suppose that the projection of the opposite vertex is on the middle point of the base.
The isRegular()
method that allows to know whether a triangle is regular or not.
The prototype of the method is as follows:
public boolean isRegular() { /* complete */ }
The method must return true
if the length of all sides of the
triangle are equal.
You need only to compare the length of the three sides of the triangle.
The toString()
method that allows to obtain a text string representation
of the object. The prototype of the method is as follows:
public String toString() { /* complete */ }
The method must return a string of characters with the values of the triangle according to some format. The output format of the text string is shown below (data values shown are only examples) :
TRIANGLE [NAME=triangle1] [NON REGULAR] : VERTEXES (1.0, 1.0),(3.0, 1.0),(2.0, 2.0)
Please, remember that what has been shown above is a formatted text string with example values for attributes. They are only used to show you how the output format is, so in the implementation of the method you must not use these values, instead of you have to work with attributes directly.
Use the toString()
method of the vertexes of the triangle.
Remember that "+" operator, applied to text strings, allows to concatenate them.
main
method of the Triangle
classNow you must create a method to test the previous code. Create a main
method
in the Triangle
class that carries out the following tasks:
Create three points.
Create a triangle from those previous points.
Display on the console a descriptive text string with the values of the triangle.
Finally, print the value of the triangle's area.
Square
class.The Square
class inherits also from Figure
and has the following implementation:
public class Square extends Figure { /** Square vertexes */ private Point vertex1; private Point vertex2; private Point vertex3; private Point vertex4; /** Constructor with name and vertexes */ public Square(String name, Point diagonalVertex1, Point diagonalVertex3) { } /** Private method to calculate the vertexes for the other diagonal*/ private void otherDiagonal(Point vertex1, Point vertex3) { } /** Method implementation to calculate the area */ public double area() { return 0; } /** Implementation of the abstract method to calculate if the figure is regular. */ public boolean isRegular() { return false; } /** Returns a representative string of the square. */ public String toString() { return null; } }
Notice that a square can be created from one of its diagonals, therefore, the constructor receives
both vertexes of the diagonal as input parameters. To calculate the other two remaining vertexes, you have to
implement another private method called otherDiagonal(Point vertex1, Point vertex3)
that calculates and
creates the other two vertexes of the second square's diagonal from those you have passed as parameters to the method,
that is, it must calculate and create both vertexes vertex2
and vertex4
of the square.
Also notice that, as it derives from the Figure
abstract class, the Square
class
is forced to implement ALL abstract methods from Figure
... Which are those?
Square
class.Download the skeleton of the Square
class from this link
Square.java
and carry out the following tasks to implement the constructor of the class.
Firstly, implement the following private method that allows to create the vertexes of the second diagonal from the two vertexes of the first diagonal. The prototype of the method is as follows:
private void otherDiagonal(Point vertex1, Point vertex3) { /* complete */ }
This method creates both two vertexes of the second square's diagonal (vertex2
and
vertex4
) on the basis of the coordinates of the vertexes of the first diagonal that are passed as
input parameters.
This is one of the proposed simplifications. For a correct solution, you would need to find the vector which is perpendicular to the defined diagonal, and then find the point to the appropiate distance. However, in order to avoid you wasting the time dealing with mathmatics, we propose you to make the following simplification: just suppose that the sides are parallel to the axis, and therefore x and y f the new vertexes are just those of the provided vertexes, but with x and y interexchanged.
Implement the constructor of the class.
Use the method that you have implemented before to calculate the square's vertexes.
Square
class.Implement the methods of the Square
class that are specified next:
Write the area()
method that allows to calculate the area of a square.
The prototype of the method is as follows:
public double area() { /* complete */ }
The method calculates the area of a square according to the following formula: Area = base X altura
Use the distance(Point anotherPoint)
method of the Point
class with the vertexes of the square.
Write the isRegular()
method that allows to calculate whether a square is a
regular figure or not. The prototype of the method is as follows:
public boolean isRegular() { /* complete */ }
This method is obvious.
Write the toString()
method that allows to obtain a text representation of the object.
The prototype of the method is as follows:
public String toString() { /* complete */ }
The method must return a string of characters with the values of the square according to some kind of format. In this case, the output format of the text string is shown below (data values shown are only examples) :
SQUARE [NAME=square1] : VERTEXES (3.0, 3.0),(5.0, 3.0),(5.0, 5.0),(3.0, 5.0)
You can reuse most of the code of the toString()
method of the triangle.
Remember that "+" operator, applied to text strings, allows to concatenate them.
main
method of the Square
classNow you must create a method to test all the previous code. Create the main
method in the Square
class that must do the next tasks:
Create two points that will be the diagonal of your figure.
Create a square from those previous points.
Display on the console a descriptive text string with the values of the square.
Finally, print the value of the square's area.
The FiguresArea
class, which contains an array of figures, is the one that will allows us to calculate the total area of a collection of figures. It has the following definition:
public class FiguresArea { /** The array of figures */ private Figure figures[] = null; /** Constructor of the class with a fixed number of figures. */ public FiguresArea(int figuresNumber) { } /** Calculates the total area of the array figures. */ public double totalArea() { return 0.0; } /** Adds a new figure in the first empty position of the figures array. */ public void addFigure (Figure f){ } /** Prints a list with the array figures. */ public void print() { } /** Main Program */ public static void main(String args[]) throws Exception { } }
The constructor of the class initialises the array with the maximum number of figures.
The addFigure()
method allows to add an object of the Figure
class at the first free position
of the array. The totalArea()
method will add the respective areas of the figures that are contained in the array and
will return the total sum of them. The print()
method must print that total area and a descriptive message for every
figure on the console.
Download the FiguresArea
class from the following link FiguresArea.java
and carry out the following task:
Implement the constructor of the class that initialises the array of figures with the maximum number of them.
FiguresArea
class.Implement the methods of the FiguresArea
class that are specified next:
Write the addFigure (Figure f)
method that allows to add an object Figure
to
the array. The prototype of the method is as follows:
public void addFigure (Figure f) { /* complete */ }
The method must add a new object Figure
to the figure's array.
According to the theory, Figure
is abstract and, therefore there could not exist any object instances from that class. Object instances are, in fact, from the subclasses of Figure
, that is: Triangle, Square
.
Write the totalArea()
method that allows to calculate the total area of the figures
of the array.The prototype of the method is as follows:
public double totalArea() { /* complete */ }
The method must calculate the total area of the figures that are contained in the array of figures. To do so, it traverses the array adding the corresponding area of each figure of the array.
Remember what it the purpose of abstract methods of the Figure
class when implementing the method.
Write the print()
method that allows to print the total area of the figures. The prototype
of the method is as follows:
public void print() { /* complete */ }
The method prints on console the result of the calculation of the total area of the figures. Use the previous method to achieve it.
You can print also what figure is and to do so, use the toString()
method of each figure.
Polymorphism is a consequence of applying inheritance to classes and it allows what is known as method overriding by which, the same method can be implemented either at the base class or the subclass. At runtime, depending on the type of the object (which class the object actually instantiates), Java's interpreter will invoke to the one of the correspondig class.
main
method of the FiguresArea
classCreate the main program that has to carry out the following tasks:
Create an object of the FiguresArea
class with two figures as maximum.
Create a figure of the Triangle
class. To do so, you will have to create previously the
3 points that constitute the vertexes of the triangle and then pass them to the constructor of Triangle
.
Create a figure of the Square
class. To do so, you will have to create previously the
2 points that constitute diagonal of the square and then pass them to the constructor of Square
.
Add the triangle and the square to the array of figures of the FiguresArea
class. Use the
method you have implemented previously to do it.
Print the result of the calculation of the total area of the figures. To do so, invoke to the corresponding method of the class.
The resolution of this exercise expects that the student learns the basics of references to a base class in inheritance hierarchies.
Download the following code listings
(
Position.java
,
Figure.java
,
Castle.java
,
Queen.java
)
and analyse both the class hierarchy and the Position
class that is going to be used.
We are going to deal with a set of figure elements. As Figure
class is abstract, we can't create instances from it, therefore, the collection of elements will be made up of objects from the Castle
and Queen
classes, indistinctly.
Implement the necessary code to hold, in the same collection and indistinctly, 2 objects of Queen
class and 4 objects of Castle
class.
Once the previous code has been implemented, traverse the collection invoking public void whoAmI()
method to test the correct operation of the base class references.
Once this exercise has been finished, answer the following questions:
Which methods can be really invoked on the collection elements?
If Castle
class has implemented void castle()
method ("enrocar" in Spanish), could it be possible to invoke that method from a reference to the base class?
What should we have to do in order to be able to use the previous void castle()
method from an object of Castle
class that is pointed by a reference to Figure
class?
What should we do to know exactly to which class belongs every object pointed by a reference to the base class?
In this exercise we are going to review the main concepts of Object Oriented Programming (OOP) in Java with an application to create a class hierarchy to define geometric figures.
IMPORTANT NOTE: Remember that it is essential that you test your code whenever you implement any method, even though you are not asked to do so explicitly.
Figure
interface.In Java, an interface represents a kind of specification for all classes that implement it. Is is normally used to define a set of methods that we want to be provided by those classes.
For example, the
Comparable interface represents
objects that can be compared among them. It defines the compareTo()
method that allows to compare two objects. Every class whose objects want to be compared, as stated before, must implement this method. With an interface, further design and reuse of code is easily made since all objects share the same comparison method and the result of it.
Before going on to the next sections, try to answer the following questions:
What is an interface?
How is it implemented in Java?
What does it mean when a class implements an interface. How do you write this in Java?
All classes that are defined in this exercise must provide a basic set of methods, such as calculating the area of a geometric figure. In Java, this is achieved by defining the interface that declares all methods that must be implemented by the classes that implement it. For this exercise, every class that is created must implement the Figure
interface.
An abstract class is a class that can not be instantiated. This is shown by the use of the abstract
keyword in its declaration. An abstract class has "at least" one abstract method. That is, a method which is only declared but not implemented. This abstract method should be implemented by any subclass of the class. There is no point in instantiating objects of an abstract class and only subclasses of it can instantiate objects.
Remember that an abstract class can have constructors, though objects from it can not be instantiated.
Write the code of the GeometricFigure
abstract class, which must store the common information for all geometric figures (for example, a descriptive label) and has to provide all methods that can be shared among figures and are independent from the concrete shape of them. This class must implement the Figure
interface. Every class that can be represented by a geometric figure will inherit from GeometricFigure
class.
Every figure will have a descriptive label, so you should define an attribute of type String
to hold the text of the label.
Write a constructor that receives as input parameter the descriptive label of the figure.
Write the get
and set
methods that allow to modify the text label's attribute. As these methods should not be modified by anybody, declare them as final
to avoid any subclass to change the code of them (method overriding).
Implement the printDescription()
method. Notice that is not an abstract method although it invokes other abstract methods. Also, to avoid subclasses to change the code of it (method overriding), declare it as final
.
The method must print a text description of the figure on the console, including the label's text, the type of figure and its area, with the following format:
Tag: C-5 Figure Type: Square Area: 25
Remember that this class must implement the Figure
interface, so it must provide the code for the complete set of methods that have been defined in such interface. These methods should be implemented with the available information in the class, that is: getTag
and printDescription
methods. It is not necessary to include those methods which are impossible to be programmed in the class (Java assumes that they are implicitly abstract), but subclasses are responsible to provide their code implementations.
The next class to implement represents a rectangle and, obviously, its name will be Rectangle
. This class inherits from GeometricFigure
and implements the Figure
interface. A rectangle is defined by two dimensions, the base and the height and both are assumed to be integer values.
Write the class declaration and its correspondings attributes.
Write the constructor and the basic accesor get
and set
methods.
Write the following methods of the class:
public String getFigureType(); public double area(); public void drawTxt();
The drawTxt()
method must print the figure on the console. For example, a rectangle of base 6 and height 3 can be printed as follows:
****** ****** ******
Download the following code
FiguresTesting
and implement the code of the main
method to create, first, an instance of Rectangle
class and then print it on the console along with its description.
Answer the following questions:
Show the difference between a class and an object.
Which steps are involved in the instantiation's process of an object?
How is an object instantiated in Java?
REMEMBER: If a class implements an interface, automatically, all subclasses of it also implement that interface, even though this is not explicitly mentioned in its declaration. Notice that Rectangle
implements the Figure
interface though you haven't mentioned it in its declaration. That is because Rectangle
inherits from a class that implements Figure
.
A square is a type of rectangle where both base and height are equals. In Java, we can easily create a Square
class by deriving it from Rectangle
class.
Write the Square
class so that it inherits from the Rectangle
class of the previous section. Square
class just only needs a constructor which receives a single input parameter: the side value. The constructor will invoke the constructor of the Rectangle
superclass with the same value for the parameters of base and height
Test the new class by adding the necessary code to FiguresTesting
class.
Notice that, thanks to inheritance, it is possible to invoke methods of the Rectangle
superclass on an object of a derived type Square
without the need of programming them again.
Answer the following questions:
What is inheritance?
How do you express in Java that one class inherits from another?
Which methods of the superclass are visible from the subclasses?
What is the meaning of method overriding?
Remember that, opposite to the rest of the methods of a class, subclasses don't automatically inherit constructors from the superclass, but they can be invoked by the use of super()
keyword.
In this section, you must improve FiguresTesting
class to provide a user interface in text mode that allows the user to choose the figure that he/she wants to print on the console, then asks for the correct parameters for each figure, creates an instance of the correct class and, finally, prints the figure description and the figure itself on the console.
Use the following menu:
1.- Create rectangle 2.- Create square 3.- Display figure 0.- Exit
If the user selects one of the 2 first options, the program must ask him/her for the correct data. If he/she selects option 3, the last figure will be printed on the console (including its description). The menu must be shown until the user select the option Exit.
To simplify the generation of the correct object from the data entered by the user, it would be useful to add a readFigureData()
method to each class. This method would receive, as an input parameter, an object of type BufferedReader
from which, it will read the data introduced by the user. Then, it would return a correct instantiated object of the class with the entered data. Declare it as a static method.
Answer the following questions:
Which type are both instantiated objects (in options 1 and 2)?
Which type is the variable that references them?
Which methods from superclass are visible from the subclass?
Can you use the same variable as a reference for diferent types of figures? Why?
This exercise tries to get an overall view of how Object Oriented Programmig allows us to reuse code, as long as we use it correctly.
Let's assume that we have a little knowledge about cypher theory with strings of characters. Let's say that we have heard of several cypher algorithms, most of them which are very difficult to implement. However, there is one called Caesar, which is based on character's rotation, that has a reasonable implementation.
Caesar's algorithm is based on the order of the alphabet characters. Each character of the input text string is replaced by an output character that is calculated by adding N positions to the letter on the alphabet. For example, if we find the 'A' character and the value of N is 3, the output character that will replace would be 'D'.
Implement an Object Oriented Programming solution that allows us to easily change this algorithm by another one which could be better in the future.
First of all, write a solution based on an abstract Cypher
class that models a generic encryption algorithm, with the basic encrypt and decrypt operations (that, for instance, receive a String and return a String), and then a CaesarCypher
class that inherits from the first one and implements the Cesar's algorithm.
Second, write a solution based on the definition of a Cryptable
interface and a CaesarCypher
class that implements it.