Academic Integrity: tutoring, explanations, and feedback — we don’t complete graded work or submit on a student’s behalf.

TASK 1: Implement abstract superclass Shape. TASK 2: Implement abstract subclass

ID: 3845785 • Letter: T

Question

TASK 1: Implement abstract superclass Shape.

TASK 2: Implement abstract subclasses TwoDimensionalShape and ThreeDimensionalShape which extend abstract superclass Shape. TwoDimensionalShape contains method getArea, and ThreeDimensionalShape contains methods getArea and getVolume

TASK 3: Implement concrete classes Circle, Square, Triangle, Sphere, Cube and Tetrahedron.

TASK 4: Create a program that uses an array of Shape references to objects of each concrete class in the hierarchy. The loop that processes all shapes in the array determines whether each shape is a TwoDimensionalShape or a ThreeDimensionalShape. If it is a TwoDimensionalShape, its area is displayed. If it’s a ThreeDimensionalShape, both its area and volume are displayed.

Shape Two DimensionalShape Circle Square Triangle Fig. 9.3 I nheritance hierarchy for Shapes Three DimensionalShape Sphere Cube Tetrahedron

Explanation / Answer

#include <iostream>
#include <cmath>
#include <stdexcept>
#include <memory>
using namespace std;

/**
* Super class
*/
class Shape
{
protected:
   int _dimensions;
public:
   Shape() : _dimensions{0}
   {};
   Shape(int dims) : _dimensions{dims}
   {};

   virtual double getArea() {};
   // Because some shapes have no volume.  
   virtual double getVolume() {};  

   void setDimensions(int dim)
   {
       this->_dimensions = dim;
   };
   int getDimensions()
   {
       return this->_dimensions;
   };
};


/**
* Extended classes
*/
class TwoDimensionalShape : public Shape
{
public:  
   TwoDimensionalShape() : Shape{2}
   {};
   // This should throw an error
   double getVolume() {
       throw logic_error("This shape ain't got area!");
   };  
};

class ThreeDimensionalShape : public Shape
{
public:  
   ThreeDimensionalShape() : Shape{3} {};
};


/**
* Final Concrete classes extending extended classes
*/
class Circle : public TwoDimensionalShape
{
protected:
   double _radius;
public:
   Circle(double r) : _radius{r}
   {};
   double getArea()
   {
       // pi*r^2
       return M_PI * pow(_radius, 2);
   }
};

class Square : public TwoDimensionalShape
{
protected:
   double _side;
public:
   Square(double s) : _side{s}
   {}
   double getArea()
   {
       // s^2
       return pow(_side, 2);
   }
};

class Triangle : public TwoDimensionalShape
{
protected:
   double _base, _height;
public:
   Triangle(double b, double h) : _base{b}, _height{h}
   {};
   double getArea()
   {
       // b*h/2
       return _base * _height / 2;
   }
};

class Sphere : public ThreeDimensionalShape
{
protected:
   double _radius;
public:
   Sphere(double r) : _radius{r}
   {}
   double getArea()
   {
       cout << 4 * M_PI * pow(_radius, 2) << endl;
       return 4 * M_PI * pow(_radius, 2);
   }
   double getVolume()
   {
       return (4/3) * M_PI * pow(_radius, 3);
   }
};

class Cube : public ThreeDimensionalShape
{
protected:
   double _side;
public:
   Cube(double s) : _side{s}
   {};
   double getArea()
   {
       // surface area = 6*a^2
       return 6 * pow(_side, 2);
   }
   double getVolume()
   {
       // a^3
       return pow(_side, 3);
   }
};

class Tetrahedron : public ThreeDimensionalShape
{
protected:
   double _side;
public:
   Tetrahedron(double s) : _side{s}
   {};
   double getArea()
   {
       // sqrt(3)*a^2
       return sqrt(3) * pow(_side, 2);
   }
   double getVolume()
   {
       // a^3/6sqrt(2)
       return pow(_side, 3) / (6 * sqrt(2));
   }
};

int main()
{
   unique_ptr<Shape> arr[2];
   arr[0] = make_unique<Circle>(10);
   arr[1] = make_unique<Sphere>(10);

   // This one is accessing the right method.
   cout << "Area of circle: " << arr[0]->getArea() << endl;  
   // This one should access the parent, but accesses the grand parent!
   // even if it is overridden in parent.
   cout << "Volume of circle: " << arr[0]->getVolume() << endl;

   // Both of these are accessing methods on grand parent rather than their own!!
   cout << "Area of sphere: " << arr[1]->getArea() << endl;
   cout << "Volume of sphere: " << arr[1]->getVolume() << endl;

   return 0;
}