2

Here's my program. Where ever there is a this.pizzaorder[i].clone() or this.pizzaorder[count].clone(), I get an error saying that the Clone() from the type Object is not visible. Any help, please?

import java.text.NumberFormat;
public class PizzaOrder {

NumberFormat moneyFormatter = NumberFormat.getCurrencyInstance();
public int TotalNoOfPizzas, keep;                                             
//declaring the variables needed for this class

public double totalcost;
Pizza[] pizzaorder = new Pizza[TotalNoOfPizzas];
int i;

public PizzaOrder() {                                              
//constructor to initialize all the varibales

    this.TotalNoOfPizzas = 0;
    this.totalcost = 0.0;
    for ( i = 1; i <= pizzaorder.length; i++ ) {
        pizzaorder[i] = null;   }
}

public PizzaOrder( PizzaOrder keep ) {                          
// copy constructor
    for ( i = 1; i <= pizzaorder.length; i++) {
        this.pizzaorder[i] = this.pizzaorder[i].clone();    }
    this.TotalNoOfPizzas = keep.TotalNoOfPizzas;
    this.totalcost = keep.totalcost;    }

public int getTotalNoOfPizzas() {                                       
//using Accessor to get the number of pizzas
    return this.TotalNoOfPizzas; }

public void setTotalNoOfPizzas( int TotalNoOfPizzas1 ) {                
//using mutators to set the number of pizzas
    this.TotalNoOfPizzas = TotalNoOfPizzas1; }

public Pizza getPizza ( int pizzas) {                                       
//using Accessor to get the size and toppings for pizza 1 
    return (this.pizzaorder[pizzas]); } 

public void setPizza(Pizza tempPizza, int count) {
    this.pizzaorder[count].clone(); }       

public double getTotalCost() {
    return(this.totalcost); }

public void setTotalCost(double totalcost1) {
    this.totalcost = totalcost1;    }



public double calcTotal() {                                                                         
//calculating the total cost
double totalcostoford = 0;
for (i = 1; i <= pizzaorder.length; i++) {
    totalcostoford += this.pizzaorder[i].calcCost();    }
return totalcostoford;  }

public String tostring() {
String pizzaDescription;
pizzaDescription = "\n Order No.:" + this.pizzaorder;
pizzaDescription +="\nTotal No. of pizza's ordered:" + TotalNoOfPizzas;
for ( i = 0; i <= pizzaorder.length; i++ ) {
    pizzaDescription += "\n" + i + ". Pizza" +       
pizzaorder[i].getPizzaDescription();  }
pizzaDescription += "\n" + moneyFormatter.format(this.getTotalCost()) + "is your     
 total price.";
return pizzaDescription;
}
}
Ry-
  • 218,210
  • 55
  • 464
  • 476
user2975261
  • 21
  • 1
  • 2
  • I added this to my program public Object clone(){ try{ return super.clone(); }catch(Exception e){ return null; } } But still it did not work :( – user2975261 Nov 10 '13 at 01:48
  • BYW, you have a typo above: `this.pizzaorder[i] = this.pizzaorder[i].clone();` should be `this.pizzaorder[i] = keep.pizzaorder[i].clone();` – Eamonn O'Brien-Strain Nov 10 '13 at 02:28

3 Answers3

1

Your initial problem is that you need to declare a public clone method in your class if you want clone to be publicly visible.

But simply doing this is NOT sufficient:

  public Object clone() { 
     try { 
         return super.clone(); 
     } catch (Exception e) { 
         return null; 
     } 
  }

There are two problems with this. First, catching exceptions and returning null like that violates the contract of how clone() is expected to behave. Read the javadoc for Object.clone() to understand how it is supposed to behave. There is no justification for returning null in the event of a failure. You should throw an exception, or allow an existing one to propagate.

And the reason that you are getting an exception is also explained by the javadoc. You are relying on Object's native cloning mechanism. But that mechanism only works if the class you are trying to clone implements the Cloneable marker interface. If it does not, then calling super.clone() will raise CloneNotSupportedException.


Finally, I would point out that you need to be careful with cloning. On the one hand, it can be expensive. On the other hand, cloning using the native clone mechanism doesn't always do "the right thing" for your application. This mechanism only gives you a shallow copy; i.e. it does not make a copy of the "component" objects of the object you are cloning.

Stephen C
  • 698,415
  • 94
  • 811
  • 1,216
0

To clone a class you need to override the clone() method, and you need to put the code in there that creates a new instance of your class and copies the member variables of the other class to it, and return the new instance.

Rick Falck
  • 1,778
  • 3
  • 15
  • 19
0

I would recommend not using clone but instead using a copy constructor.

To the Pizza class, add a copy constructor:

class Pizza {
   private final sometype some field;
   ...
   Pizza(Pizza that) {
       this.somefield = that.somefield;
   }
   ...

Then instead of

this.pizzaorder[i] = keep.pizzaorder[i].clone();

do

this.pizzaorder[i] = new Pizza(keep.pizzaorder[i]);

IMHO, this is cleaner and easier to understand.

Eamonn O'Brien-Strain
  • 3,352
  • 1
  • 23
  • 33