1

Please Note: I created a post earlier that had this question along with several others, but was told that since I was asking so many questions in the same post, it'd be better to break it up into individual questions. So please do not mark this as a duplicate, yes the instructions are the same and yes the same code is being used, but the question itself is different. Thanks.

I'm working on a program with the following instructions:

Write a class named Octagon that extends GeometricObject and implements the Comparable and Cloneable interfaces. Assume that all 8 sides of the octagon are of equal size. The area can be computed using the following formula

area = (2 + 4/square root of 2) * side * side 

Write a program (driver) to read in a series of values from a file, display the area and perimeter, create a clone and compare the object and its clone (based on the area). In addition, your program should compare the current object (just read in) with the first object read in. The program ends when a negative number is read from the file.

Here is the code I have so far, This is my GeometricObject Class:

public abstract class GeometricObject {

    public abstract double getArea();
    public abstract double getPerimeter(); 
}

My Octagon class:

public class Octagon extends GeometricObject implements Comparable<Octagon>, Cloneable {

    private double side;

    public Octagon() {
    }

    public Octagon(double side) {
        this.side = side;
    }

    public double getSide() {
        return side;
    }

    public void setSide(double side) {
        this.side = side;
    }

    public double getArea() {
        return (2 + (4 / (Math.sqrt(2))) * side * side); 
    }

    public double getPerimeter() {
        return side * 8;
    }

    public String toString() {
        return "Area: " + getArea() + "\nPerimeter: " 
            + getPerimeter() + "\nClone Compare: " +  "\nFirst Compare: ";
    }

    public int compareTo(Octagon octagon) {
        if(getArea() > octagon.getArea()) 
            return 1;
        else if(getArea() < octagon.getArea()) 
                return -1;
        else
            return 0;
    }

    @Override 
    public Octagon clone() {
        return new Octagon(this.side);
    } 
}

And my Driver or tester class: (This is where I need the most help):

import java.util.*;

public class Driver {
    public static void main(String[] args) throws Exception {
        java.io.File file = new java.io.File("prog7.dat");
        Scanner fin = new Scanner(file);
        Octagon first = null;
        int i = 1;
        Octagon older;

        while(fin.hasNext())
        {
            double side = fin.nextDouble();
            if(side < 0.0)
                break;
            Octagon oct = new Octagon(side);
            System.out.print("Octagon " + i + ": \"" + oct.toString() + "\"");
            if (first == null) {
                first = oct;
                System.out.print("Equal");
            }
            else {
                int comparison = oct.compareTo(first);
                if (comparison < 0)
                    System.out.print("less than first");
                else if (comparison > 0)
                    System.out.print("greater than first");
                else 
                    System.out.print("equal");
            }
            String cloneComparison = "Clone Compare: ";
            older = oct;
            Octagon clone = oct.clone();
            if ( older.getArea() == clone.getArea() ){
                cloneComparison = cloneComparison + "Equal";
            } else {
                cloneComparison = cloneComparison + "Not Equal";
            }
            //System.out.println(cloneComparison);
            i++; 
            first = new Octagon(side);
            System.out.println();
        }
        fin.close();
    }
}

And here is the file being used to get the input. Each line is one octagon:

5.0
7.5
3.26
0.0
-1.0

I'm having a hard time figuring out how I would implement the Cloneable Interface so that when I print out the results, they will say Clone Comparison: Equal (or not equal).

Any input is greatly appreciated.

  • Why do you compare area? Just compare the sides. Area is a double computed using sqrt(2), you can't just compare it w/o considering floating point error... – Jaa-c Aug 04 '14 at 23:10
  • Because that's what the directions said to do. –  Aug 04 '14 at 23:11
  • Do you really mean [`Cloneable`](http://docs.oracle.com/javase/7/docs/api/java/lang/Cloneable.html)? May be you need `Comparable`? – PM 77-1 Aug 04 '14 at 23:11
  • Yes, I'm using Comparable as well, but also need to use Cloneable (we're supposed to make a clone of each object read in and compare that to the original of that object). –  Aug 04 '14 at 23:15
  • Whether you implement `Cloneable` or not makes no difference if you do not call through to `Object.clone()`. – newacct Aug 06 '14 at 08:21

1 Answers1

0

What I would do is first implement the method Octagon.clone() by creating an Octagon with the same side length

Public Octagon clone(){
    return new Octagon(this.side);
}

In Driver have it clone your newly created Octagon and compare the two (older and newer) with something like this:

String cloneComparison = "Clone Comparision: ";
if ( older.getArea() == newer.getArea() ){
    cloneComparison = cloneComparison + "Equal";
} else {
    cloneComparison = cloneComparison + "Not Equal";
}
System.println(cloneComparison);

Which also returns the correct string depending on the result.

Sivver
  • 34
  • 4
  • On the Octagon.clone() part, would this be another method in addition to the one I already have "@Override Octagon clone() { ..." or simply changing the code inside that existing method to be this.getSide() rather than this.side like it's written now? –  Aug 04 '14 at 23:23
  • @Beth What you've done already is fine: `this.side` vs `this.getSide()` is immaterial really. I'm not clear what your actual question is. – user207421 Aug 04 '14 at 23:29
  • Oh ok, just wanted to make sure, like I said I've never used this before so am still learning how everything works. –  Aug 04 '14 at 23:30
  • @BethTanner if you already have an `Octagon.clone()` method you should be fine to see if it works. **This.side** is actually the better way of retrieving the field- I'll change my answer to reflect that – Sivver Aug 04 '14 at 23:36
  • I'm having some trouble getting it to compile as this is written. on the older.getArea() and newer.getArea() I'm assuming these are variables that would need to be declared (older and newer) but am having trouble figuring out how that should be done? –  Aug 04 '14 at 23:37
  • 1
    *older* and *newer* are just variables representing the older (original) and newer (clone) Octagons. The older Octagon would be your **oct** variable and the newer one (we'll call it **clone** here) would need to be created by cloning it: `Octagon clone = oct.clone();` Once you have both you should be able to run comparisons on them. – Sivver Aug 04 '14 at 23:40
  • My only problem now is getting it to print correctly. See, I'm wanting it to print from the toString() method like the area and perimeter is doing, rather than with a print statement in Driver, any suggestions? Otherwise this works great! –  Aug 04 '14 at 23:53
  • From the javadocs of `Object`: "By convention, the returned object should be obtained by calling super.clone". So this implementation is not recommended. Not that _any_ implementation of `clone()` is recommended: see [this answer](http://stackoverflow.com/questions/11905630/java-super-clone-method-and-inheritance) for a good explanation why. – Paul Hicks Aug 05 '14 at 00:33