1. Create a generic Shape class having methods to determine the area and perimeter of a shape, and then create an appropriate class hierarchy for the following specific shapes: circles, equilateral triangles, squares, rectangles, and pentagons. Note that a square is a special rectangle whose length is equal to its width.
The Shape class should also include a static variable to keep track of the number of shapes that has been initiated at any time. Then, illustrate polymorphic behavior by creating shapes of each type and determining their area and perimeter using references to the generic shape.
Each class will need constructors capable of creating the appropriate objects. For circles, the constructor will need the radius r. For equilateral triangles, the constructor will need the length of a side s. For rectangles, the constructor will need the length l and width w. For squares, the constructor will need the length of a side s. For pentagons, the constructor will need the length of a side s.
Each of these classes will contain area, perimeter, and toString methods, returning the area, perimeter, and a string representation of the shape respectively. Shape class itself will not be instantiable. Decide on and implement an efficient way to report the number of shapes that has been initiated at any time.
2. Replace the abstract class Shape in (1) above by an interface called Shape, and make all of the former classes of Shape implement the new interface. Create a test program that calls the interface methods with Circles, Triangles, etc, to show that the interface calls the proper version of each method for each object.