2016-05-18 23 views
0

Ich versuche, eine tiefe Kopie einer Klasse zu erstellen. Hier ist die Klasse im kopieren versucht, und die letzte Methode ist die Kopie eines:Wie unterscheidet sich das Klonen von der Zuweisung von Werten (warum sollte die Implementierung der Schnittstelle Cloneable erfolgen)?

import java.util.ArrayList; 
import java.util.List; 

public class catalog implements Cloneable{ 

    List<product> cat = new ArrayList<>(); 
    int counter; 
    final int capacity = 2; 

    public void addProduct(product x){ 
     cat.add(x); 
    } 
    public void addProduct(String name, int id, int price, int stock) throws Exception{ 
     for(int i = 0; i < cat.size(); i++){ 
       product temp = cat.get(i); 
       if(temp.name == name){ 
        temp.stock = temp.stock + stock; 
        return; 
       } 
       if(temp.id == id){ 
        System.out.println("Product with this ID already exists"); 
        return; 
       } 
     } 
     if(cat.size() >= capacity){ 
      //throw new customException("Not enough capacity"); 
      throw new customException(); 
     } 
     product temp = new product(); 
     temp.name = name; 
     temp.id = id; 
     temp.price = price; 
     temp.stock = stock; 
     cat.add(temp); 
     } 
    public void showSelection(){ 
     for(product temp : cat){ 
      System.out.println("Product " + temp.name + " ID: " + temp.id 
        + " Price: " + temp.price + " In stock: " + temp.stock); 
     } 
    } 
    public void removeFromStock(String name){ 
     for(int i = 0; i < cat.size(); i++){ 
      product temp = cat.get(i); 
      if(temp.name == name){ 
       temp.stock = temp.stock - 1; 
       cat.set(i, temp); 
      } 
     } 
    } 

    public Object clone(){ 
     catalog b = new catalog(); 
     for(int i = 0; i <= cat.size(); i++){ 
      product temp, temp1; 
      temp1 = cat.get(i); 
      temp = (product)temp1.clone(); 
      b.addProduct(temp); 
     } 
     return b; 
    } 
} 

Und hier ist der Haupt:

public class testMoney { 

    public static void main(String[] args) { 

     automatasklase test = new automatasklase(); 
     test.addMoney(50); 
     System.out.println(test.getMoney()); 
     product cola = new product(); 
     cola.id = 1; 
     cola.price = 2; 
     cola.name = "Cola"; 
     productsExpire Milk = new productsExpire(); 
     Milk.name = "Milk"; 
     Milk.id = 2; 
     Milk.price = 10; 
     Milk.stock = 10; 
     Milk.isExpired = true; 
     catalog menu = new catalog(); 
     menu.addProduct(cola); 
     menu.addProduct(Milk); 
     menu.showSelection(); 
     try{ 
     menu.addProduct("Pepsi" ,3, 5, 108); 
     }catch(Exception e){ 
      System.out.println("Exception occured = " +e); 
     } 
     try { 
      menu.addProduct("Cola", 1, 3, 7); 
     } catch (Exception e) { 
      System.out.println("Exception occured = " + e.getMessage()); 
     } 
     menu.showSelection(); 
     test.buyProduct(menu, 2); 
     System.out.println(test.getMoney()); 
     menu.showSelection(); 
     Milk.isAvailable(); 
     product copyy = (product)cola.clone(); 
     System.out.println("-------------"); 
     System.out.println(cola.id + cola.name + cola.price + cola.stock); 
     System.out.println(copyy.id + copyy.name + copyy.price + copyy.stock); 

     // BELOW THE PROBLEM OCCURS!!! 

     catalog newtest = (catalog) menu.clone(); 

     // ABOVE THE IS THE PROBLEM!!!! 

    } 

} 

Das Problem ist wie folgt:

Exception in thread "main" java.lang.IndexOutOfBoundsException: Index: 2, Size: 2 
    at java.util.ArrayList.rangeCheck(Unknown Source) 
    at java.util.ArrayList.get(Unknown Source) 
    at AutomatasA.catalog.clone(catalog.java:58) 
    at AutomatasA.testMoney.main(testMoney.java:46) 

Sie werden bemerken, dass ich bereits ein Produktklassenobjekt in der clone-Methode des Katalogs selbst kloniere, aber wie Sie vielleicht bemerken, hat die Hauptklasse es bereits getestet und funktioniert, sodass das Klonen des Klassenprodukts erfolgreich war .

Können Sie das Problem? Ich weiß, es wird auch eine Menge kleiner Fehler bei der Codierung der Etikette und vielleicht leichtere Möglichkeiten geben, Dinge zu tun, aber ich bin nur ein Anfänger. Ich muß tiefe Kopie implementieren, und es hat etwas bedeuten, so das Klonen der Produktklasse ist nicht genug, ich will einen ganzen Katalog ein Verfahren schaffen für das Klonen, also wenn die Maschine war mit einem neueren ersetzt werden, Sie könnte nur diese Methode verwenden.

Durch die Art und Weise des gesamte Projekt einen Code für eine virtuelle Maschine Snack schafft, wie die, wo Sie Geld einzugeben, drücken Sie eine Nummer des Artikels, den Sie mögen, und dann bekommen.

Vielen Dank für Ihre Hilfe!

+0

Verwenden Sie das Klonen nicht, wenn Sie eine tiefe Kopie benötigen. – shmosel

+0

Warum? Ich nehme Kurse in meiner Muttersprache und beide Methoden werden gleich genannt. Was ist der Unterschied zwischen ihnen? – Gytis39

Antwort

1

Ihre Ausnahme wird durch diese Linie verursacht:

for(int i = 0; i <= cat.size(); i++){ 

Es sollte

for(int i = 0; i < cat.size(); i++){ 

sein, aber Sie sollten wirklich nicht Ihre eigene tiefe Klon so umsetzen. Wenn Sie eine Kopie erstellen möchten, erstellen Sie eine separate Methode oder einen Kopierkonstruktor.

+0

Danke, es hat mein Problem absolut behoben! Aber Sie sagten, ich sollte eine separate Methode dafür erstellen, mache ich es nicht? Ich mache das Kopieren in der Methode namens Klon. – Gytis39

+0

@ Gytis39 Sie das Überschreiben der [ 'Object.clone()'] (https://docs.oracle.com/javase/7/docs/api/java/lang/Object.html#clone()) Verfahren, welches per Konvention seine Kopie über 'super.clone()' erstellen soll. Ihre Methode tut das nicht, was bedeutet, dass es keinen Grund gibt, die 'clone()' Methode zu überschreiben oder sogar 'Cloneable' zu ​​implementieren. – shmosel