PDA

View Full Version : Help with Cloneable and Comparable


autokustomizer
10-13-2009, 10:38 PM
I am writing these programs, and I am stuck. The instructions are:
-Write a class named Octagon that extends GeometricObject and implements the Comparable and Cloneable interfaces
-Assume all eight sides are of equal length
-Area is computed by : area = (2+4/sqrt(2))side*side
-The test program creates an Octagon with side value of 5 and displays its area and perimeter.
-Create a new object using the clone method and compare the two objects using the compareTo method.

Here is my GeometricObject program:

public abstract class GeometricObject
{
//data fields
private String color = "white";
private boolean filled;
private java.util.Date dateCreated;

//default constructor
protected GeometricObject()
{
dateCreated = new java.util.Date();
}

public String getColor()
{
return color;
}

public void setColor(String color)
{
this.color = color;
}

public boolean isFilled()
{
return filled;
}

public void setFilled(boolean filled)
{
this.filled = filled;
}

public java.util.Date getDateCreated()
{
return dateCreated;
}

public String toString()
{
return "Created on: " + dateCreated + "\nColor: " + color + " and filled: " + filled;
}

public abstract double getArea();

public abstract double getPerimeter();
}


That compiles fine, and here is my Octagon program...


public abstract class Octagon extends GeometricObject implements Comparable, Cloneable
{
private double side = 1.0;
protected native Object clone() throws CloneNotSupportedException;

public Octagon()
{
}

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

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

public double getSide(double side)
{
return side;
}

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

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

public String toString()
{
return "The length of each side is: " + side;
}

public int compareTo(Octagon octagon1)
{
if (getArea() >= ((Octagon)octagon1).getArea())
return 1;

else if (getArea() < ((Octagon)octagon1).getArea())
return -1;

else
return 0;
}

public interface Cloneable
{
}


}


And here is what I have for my tester program, but I have no idea how to create a tester for abstract methods when I can't use the 'new' operator... Can anyone help me?


import java.util.*;

public class OctagonTester
{
public static void main(String[] args) throws CloneNotSupportedException

{
Octagon octagon1 = (Octagon)octagon1.clone();

}


}


And that throws an error...


----jGRASP exec: javac -g C:\Users\Christopher\Documents\GeometricObject.java


----jGRASP: operation complete.

----jGRASP exec: javac -g C:\Users\Christopher\Documents\Octagon.java


----jGRASP: operation complete.

----jGRASP exec: javac -g C:\Users\Christopher\Documents\OctagonTester.java

OctagonTester.java:13: variable octagon1 might not have been initialized
Octagon octagon1 = (Octagon)octagon1.clone();
^
1 error

----jGRASP wedge2: exit code for process is 1.
----jGRASP: operation complete.


Please help...TY in advance...

cs_student
10-14-2009, 01:13 AM
First, why is your clone method protected and native?

Second, why do you create Coneable interface? It already exists (http://java.sun.com/j2se/1.4.2/docs/api/java/lang/Cloneable.html).

As to why it's not compiling, because you may not have an initialized object (which you don't).

clone() is not a static method (so you have to call it on a already created object).
It's also not a public method, so you can't call it outside the scope of that class.

Also your Octagon class is abstract, so you can't create a new instance of it like you would be able to with a normal class. I don't believe that the Octagon class is supposed to be abstract.

If it wasn't abstract you would do something like


GeometricObject obj1 = new Octagon();
Octagon obj2 = new Octagon();


cs_student

autokustomizer
10-14-2009, 01:37 AM
I don't know the answer to your first question, I'm taking an online class, and I am teaching this to myself, and the book does a piss poor job of explaining this chapter,,,,very dissappointing actually... I thought that I had to create the empty constructor for implimentation reasons...It has to be abstract because of the compareTo method...I have no idea how to instianate anything when it comes to abstract, comparable, and cloneable all in the same program.....

Fou-Lu
10-14-2009, 01:49 AM
It has to be abstract because of the compareTo method...

Come again? Comparable does not need to be implemented on an abstract class. But so long as you're abstract you can never initialize it.
If you need to use a cloner outside of a class (I'm personally a fan of the copy-constructor technique), than implement Cloneable on a class and override the clone method inherited from java.lang.Object.
To use the comparable interface, you need to change its definition (to match you're implementation):

public class Octagon implements Comparable<Octagon>

Than in you're compareTo:

public int compareTo(Octagon octagon1)
{
if (getArea() >= octagon1.getArea())
return 1;

else if (getArea() < octagon1.getArea())
return -1;

else
return 0;
}

There is no need to cast these, but if you wanted you can implement Comparable on the GeometricObject since the getArea method is available on that object (in which case you'd use a Comparable<GeometricObject> instead, noting that on the abstract it has no way to determine what the shape type is).


Y'know, I'm trying to recall if you actually need to override the clone method. Although the Object.clone is protected, can somebody confirm with a test if the JVM will call this method when it comes across a class that implements Cloneable?

cs_student
10-14-2009, 01:52 AM
The Octagon class does not have to be abstract because of the compareTo method. Many classes which are not abstract implement the compareTo method.

You should have a look at the Java Trail (http://java.sun.com/docs/books/tutorial/). It's a great resource for those who are just learning java.

Also, the Jaca API Documentation (http://java.sun.com/j2se/1.4.2/docs/api/) will probably come in handy.


cs_student

autokustomizer
10-14-2009, 02:16 AM
Thank you, that compiles with no errors... But, I am still unsure of how to even start my tester program with the requirements that the instructor gave... This is what i have... GeometricObject - untouched
Octagon :


public abstract class Octagon extends GeometricObject implements Comparable<Octagon>
{
private double side = 1.0;
protected native Object clone() throws CloneNotSupportedException;


public Octagon()
{
}

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



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

public double getSide(double side)
{
return side;
}

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

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

public String toString()
{
return "The length of each side is: " + side;
}

public int compareTo(Octagon octagon1)
{
if (getArea() >= octagon1.getArea())
return 1;

else if (getArea() < octagon1.getArea())
return -1;

else
return 0;
}

public interface Cloneable
{
}

}


and my tester is basically empty...



import java.util.*;

public class OctagonTester
{

public static void main(String[] args) throws CloneNotSupportedException

{


}


}

I still need to create a new object, and I can't figure out how to...

Fou-Lu
10-14-2009, 02:37 AM
Remove the nested clone interface and the protected native clone. Implement Cloneable on the class (like I said, I can't be 100% certain but I'm thinking you can actually skip the clone method override since this is all primitive), and convert Octagon into a concrete class by dropping the abstract off of it.
There is no indication in you're instructions that Octagon needs to be abstract.

autokustomizer
10-14-2009, 02:58 AM
I know, but in my GeometricObject class, I do, and I can't remember exactly what the error is, but one shows up....

Fou-Lu
10-14-2009, 03:09 AM
GeometricObject is required to be abstract since the calculations for area and perimeter need a concreate to solve. Since these methods are flagged as abstract, the entire class must be abstract since there is no implementation details for these methods.
The error will more or less indicate that one or more methods in GeometricObject are classified as abstract and therefore the class must be classified as abstract. But in more technical sounding terms ;)

autokustomizer
10-14-2009, 03:22 AM
Its all taken care of, thank you for all of the help!!!! I didn't touch the GeometricObject class, but here is my modified Octagon class....



public class Octagon extends GeometricObject implements Comparable<Octagon>
{
private double side = 1.0;
protected native Object clone() throws CloneNotSupportedException;


public Octagon()
{
}

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



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

public double getSide(double side)
{
return side;
}

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

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

public String toString()
{
return "The length of each side is: " + side;
}

public int compareTo(Octagon octagon1)
{
if (getArea() >= octagon1.getArea())
return 1;

else if (getArea() < octagon1.getArea())
return -1;

else
return 0;
}

public interface Cloneable
{
}

}