Title: Polymorphism Shapes
Course: CPS 161: An Intro to Programming with Java - DL MM MASTER

Abstract Shape and Shape Interface

Abstract Shape

Shape.java


package shapes_abstract_shape;

public abstract class Shape {

    private static int count=0;
    public static int getCount()
    {
        return count;
    }
    public Shape()
    {
        count += 1;
    }

    public abstract double getPerimeter();
    public abstract double getArea();
    public double getAreaPerimeterRatio()
    {
        double ratio = getArea() / getPerimeter();
        return ratio;
    }
}

class Rectangle extends Shape
{
    private double width, height;

    private static int count=0;

    public static int getCount()
    {
        return count;
    }


    public Rectangle(double width, double height)
    {
        this.width = width;
        this.height = height;
        count += 1;
    }

    public double getWidth()
    {
        return width;
    }
    public double getHeight()
    {
        return height;
    }

    public double getArea()
    {
        return width*height;
    }
    public double getPerimeter()
    {
        return 2*(width + height);
    }
}

class Square extends Rectangle
{
    private static int count=0;

    public static int getCount()
    {
        return count;
    }

    public Square(double side)
    {
        super(side,side);
        count += 1;
    }
    public double getSide()
    {
        return getWidth();
    }
}

class Circle extends Shape
{
    private double radius;
    private static int count=0;

    public static int getCount()
    {
        return count;
    }


    public Circle(double radius)
    {
        this.radius = radius;
        count +=1;
    }
    public double getRadius()
    {
        return radius;
    }
    public double getArea()
    {
        return Math.PI * radius * radius;
    }
    public double getPerimeter()
    {
        return 2 * Math.PI * radius;
    }
}

class Triangle extends Shape
{
    private double side_a, side_b, side_c;
    private static int count=0;

    public static int getCount()
    {
        return count;
    }


    public Triangle(double side_a, double side_b, double side_c)
    {
        this.side_a = side_a;
        this.side_b = side_b;
        this.side_c = side_c;
        count +=1;
    }
    public double getSide_a()
    {
        return side_a;
    }
    public double getSide_b()
    {
        return side_b;
    }
    public double getSide_c()
    {
        return side_c;
    }
    public double getArea()
    {
        double s = (side_a + side_b + side_c)/2;
        double area = Math.sqrt(s* (s-side_a)*(s-side_b)*(s-side_c));
        return area;
    }
    public double getPerimeter()
    {
        return side_a + side_b + side_c;
    }
}


class RegularPolygon extends Shape
{
    private int numSides;
    private double side;
    private static int count=0;

    public static int getCount()
    {
        return count;
    }



    public RegularPolygon(int numSides, double side)
    {
        this.numSides = numSides;
        this.side = side;
        count += 1;
    }
    public int getNumSides()
    {
        return numSides;
    }
    public double getSide()
    {
        return side;
    }
    public double getArea()
    {
        double area = (numSides * side * side)  / (4 * Math.tan(Math.PI/numSides));
        return area;
    }
    public double getPerimeter()
    {
        return numSides * side;
    }
}


DemoShapes.java with Abstract Shape


package shapes_abstract_shape;

public class DemoShapesArray {

    public static void whatIsThis(Shape s)
    {

        if (s instanceof Square)
        {
            // The book calls this Downcasting
            Square square = (Square)s;
            double side = square.getSide();
            System.out.println("Square with a side of : "+ side);
        }
        else if (s instanceof Rectangle)
        {
            Rectangle rectangle = (Rectangle)s;
            double width = rectangle.getWidth();
            double height = rectangle.getHeight();
            System.out.println("Rectangle, width=" + width + " height="+ height);
        }
        else if (s instanceof Circle)
        {
            Circle circle = (Circle)s;
            double radius = circle.getRadius();
            System.out.println("Circle with a radius of " + radius);
        }
        else if (s instanceof Triangle)
        {
            Triangle triangle = (Triangle)s;
            double a = triangle.getSide_a();
            double b = triangle.getSide_b();
            double c = triangle.getSide_c();
            System.out.println("Triangle with sides " + a +" " +b + " "+c);
        }
        else if (s instanceof RegularPolygon)
        {
            RegularPolygon regularPolygon = (RegularPolygon)s;
            int numSides = regularPolygon.getNumSides();
            double side = regularPolygon.getSide();
            System.out.println("RegularPolygon with numsides="+numSides + " side="+side);
        }
        else if (s instanceof Shape)
        {
            // What happens if this had been the first thing we had checked???
            System.out.println("Shape is all this thing is");
        }
    }


    public static void main(String[] args) {
        Shape[] arr= new Shape[6];

        //arr[0] = new Shape();
        arr[0] = new Circle(2);
        arr[1] = new Rectangle(5,10);
        arr[2] = new Square(5);
        arr[3] = new Circle(1);
        arr[4] = new Triangle(3,3,3);
        arr[5] = new RegularPolygon(5,3);

        for (int i=0; i < arr.length; i++)
        {
            Shape s = arr[i];
            double area = s.getArea();
            double perimeter = s.getPerimeter();
            double ratio = s.getAreaPerimeterRatio();

            System.out.println("**************************************");
            whatIsThis(s);
            System.out.println("area="+ area + " perimeter="+ perimeter);
            System.out.println ("Ratio =" + ratio);
        }


        System.out.println("==============  Counts ================================");
        System.out.println("Shape Count = " + Shape.getCount());
        System.out.println("Rectangle Count = " + Rectangle.getCount());
        System.out.println("Square Count = " + Square.getCount());
        System.out.println("Circle Count = " + Circle.getCount());
        System.out.println("Triangle Count = " + Triangle.getCount());
        System.out.println("RegularPolygon Count = " + RegularPolygon.getCount());

        // The above is the preferred approach for accessing static things.  However the following also works:
        // Note that this uses "Early Binding .... the compiler makes the decisions

        Rectangle r = new Rectangle(1,2);
        System.out.println("Rectangle count using an object (non-preferred approach: "+ r.getCount());
        Shape s2 = r; // Note that r and s2 are the same object but the produce different results calling getCount()
        System.out.println("Shape count using an object (non-preferred approach: "+ s2.getCount());

    }

}





Shape.java based on a Interface

package shapes_interface_shape;

public interface Shape {
    public double getArea();
    public double getPerimeter();
    public double getAreaPerimeterRatio();

}


Note that DemoShapesArray.java is the same as for the Abstract version of the Shapes.java

ClassImplementingShape.java

package shapes_interface_shape;

class Rectangle implements Shape
{
    private double width, height;

    private static int count=0;

    public static int getCount()
    {
        return count;
    }


    public Rectangle(double width, double height)
    {
        this.width = width;
        this.height = height;
        count += 1;
    }

    public double getWidth()
    {
        return width;
    }
    public double getHeight()
    {
        return height;
    }

    public double getArea()
    {
        return width*height;
    }
    public double getPerimeter()
    {
        return 2*(width + height);
    }

    public double getAreaPerimeterRatio()
    {
        double ratio = getArea() / getPerimeter();
        return ratio;
    }
}

class Square extends Rectangle
{
    private static int count=0;

    public static int getCount()
    {
        return count;
    }

    public Square(double side)
    {
        super(side,side);
        count += 1;
    }
    public double getSide()
    {
        return getWidth();
    }
}

class Circle implements Shape
{
    private double radius;
    private static int count=0;

    public static int getCount()
    {
        return count;
    }


    public Circle(double radius)
    {
        this.radius = radius;
        count +=1;
    }
    public double getRadius()
    {
        return radius;
    }
    public double getArea()
    {
        return Math.PI * radius * radius;
    }
    public double getPerimeter()
    {
        return 2 * Math.PI * radius;
    }

    public double getAreaPerimeterRatio()
    {
        double ratio = getArea() / getPerimeter();
        return ratio;
    }
}

class Triangle implements Shape
{
    private double side_a, side_b, side_c;
    private static int count=0;

    public static int getCount()
    {
        return count;
    }


    public Triangle(double side_a, double side_b, double side_c)
    {
        this.side_a = side_a;
        this.side_b = side_b;
        this.side_c = side_c;
        count +=1;
    }
    public double getSide_a()
    {
        return side_a;
    }
    public double getSide_b()
    {
        return side_b;
    }
    public double getSide_c()
    {
        return side_c;
    }
    public double getArea()
    {
        double s = (side_a + side_b + side_c)/2;
        double area = Math.sqrt(s* (s-side_a)*(s-side_b)*(s-side_c));
        return area;
    }
    public double getPerimeter()
    {
        return side_a + side_b + side_c;
    }

    public double getAreaPerimeterRatio()
    {
        double ratio = getArea() / getPerimeter();
        return ratio;
    }
}


class RegularPolygon implements Shape
{
    private int numSides;
    private double side;
    private static int count=0;

    public static int getCount()
    {
        return count;
    }



    public RegularPolygon(int numSides, double side)
    {
        this.numSides = numSides;
        this.side = side;
        count += 1;
    }
    public int getNumSides()
    {
        return numSides;
    }
    public double getSide()
    {
        return side;
    }
    public double getArea()
    {
        double area = (numSides * side * side)  / (4 * Math.tan(Math.PI/numSides));
        return area;
    }
    public double getPerimeter()
    {
        return numSides * side;
    }

    public double getAreaPerimeterRatio()
    {
        double ratio = getArea() / getPerimeter();
        return ratio;
    }
}


Last Modified: December 23, 2014 3:08 PM