Avatar billede aslan Nybegynder
14. maj 2002 - 13:51 Der er 12 kommentarer og
1 løsning

skabe en clone?

Er der lige en der kan gøre mig klogere og fortælle mig hvorfor min cloning af barn ikke virker?

class Fritidshjem implements Cloneable
{


    Fritidshjem()
    {

        Børn barn = new Børn("Mette",8);

        System.out.println(barn);

        Børn klonBarn = (Børn) barn.clone();

        System.out.println(klonBarn);


    }


    public static void main(String[] aslan)
    {
        new Fritidshjem();
    }
}

class Børn
{
    String navn;
    int alder;

    Børn(String n,int a)
    {
        navn = n;
        alder = a;
    }
    public String toString()
    {
        return navn+" "+alder;
    }
}


fejlen er:

C:\Documents and Settings\aslan\Skrivebord\clone\Fritidshjem.java:12: clone() has protected access in java.lang.Object
        Børn klonBarn = (Børn) barn.clone();
                                          ^
1 error

Tool completed with exit code 1
Avatar billede carstenknudsen Nybegynder
14. maj 2002 - 13:57 #1
Fordi clone metoden nedarvet fra Object
er erklæret protected, dvs. man ikke
kan kalde den udenfor klassen eller
i en underklasse. Du er i Fritidshjem
der ikke er en subklasse til Børn.
Avatar billede aslan Nybegynder
14. maj 2002 - 14:02 #2
Så hvad gør jeg så?
Avatar billede carstenknudsen Nybegynder
14. maj 2002 - 14:06 #3
Erklær en public metode i Børn:
public Børn getClone() {
return (Børn)clone();
}
men husk at det er Børn og ikke Fritidshjem
som skal have implements Cloneable!
Avatar billede aslan Nybegynder
14. maj 2002 - 14:17 #4
Giver fejl igen:


class Fritidshjem
{


    Fritidshjem()
    {

        Børn barn = new Børn("Mette",8);

        System.out.println(barn);

        //Børn klonBarn = (Børn) barn.clone();

        //System.out.println(klonBarn);


    }


    public static void main(String[] aslan)
    {
        new Fritidshjem();
    }

}

class Børn implements Cloneable
{

    String navn;
    int alder;

    Børn(String n,int a)
    {
        navn = n;
        alder = a;
    }

    public String toString()
    {
        return navn+" "+alder;
    }
try{
      public Børn getClone()
      {
          return (Børn) clone();
      }

  } catch(CloneNotSupportedException e) {}



}


C:\Documents and Settings\aslan\Skrivebord\clone\Fritidshjem.java:43: illegal start of type
try{
^
C:\Documents and Settings\aslan\Skrivebord\clone\Fritidshjem.java:49: <identifier> expected
  } catch(CloneNotSupportedException e) {}
                                          ^
2 errors

Tool completed with exit code 1
Avatar billede carstenknudsen Nybegynder
14. maj 2002 - 14:21 #5
Du skal skrive
public Børn getClone() throws CloneNotSupportedException {
...
}
eller fange exception'en inde i getClone
metoden, det går altid godt i dit tilfælde:
public Børn getClone() {
try {
return (Børn)clone();
}
catch(CloneNotSupportedException e){}
return null; // bliver aldrig udført
}
Avatar billede aslan Nybegynder
14. maj 2002 - 14:24 #6
ehm ok det virker, men hvor kloner jeg så barnet henne?
Avatar billede carstenknudsen Nybegynder
14. maj 2002 - 14:27 #7
Det gør getClone metoden, den kalder clone
der gør arbejdet for dig, sålænge du ikke
bruger arrays men kun simple objekter som
du gør i ovenstående. Du kalder metoden
fra Fritidshjem klassen hvor du før
forsøgte at kalde clone direkte.
Avatar billede aslan Nybegynder
14. maj 2002 - 14:31 #8
ok tak det virker, men java plejer at være skide smart så jeg kan ikke lige se at det skal være så indviklet at clone en objekt?
Avatar billede carstenknudsen Nybegynder
14. maj 2002 - 14:39 #9
Du skal huske på at det er dig der definerer
nye klasser og objekter og derfor kun dig
der ved hvordan man kloner dem fornuftigt.
Jeg vil gerne smide en klasse op du kan bruge
der udnytter serialisering istedet for clone
der ligger bare en statisk metode der laver
en kopi af et objekt der kan serialiseres,
dvs implementerer Serializable istedet for
Cloneable. Det vil bare sige at objektet
kan sendes gennem streams (til og fra filer
og over et netværk). Sig til så smider
jeg den op.
Avatar billede aslan Nybegynder
14. maj 2002 - 14:40 #10
Meget gerne tak!
Avatar billede carstenknudsen Nybegynder
14. maj 2002 - 14:42 #11
import java.io.*;
import javax.swing.*;

/**
* The class Serialization provides methods for
* saving objects to files and loading objects from files.
* The implementation is based on code from <I>Java Examples in a nutshell</I>.
* <BR><B>Examples of use:</B><BR>
* <PRE>
* try {
*  Serializable o = ...;
*  Serialization.save( o, "object.ser" );
*  ...
*  Serializable u = Serialization.load( "object.ser" );
*  ...
*  Serializable v = Serialization.load( Serialization.loadFile() ); // interactive loading
*  ...
*  Serializable copy = Serialization.deepclone( u ); // bit for bit copy of u
* }
* catch ( IOException ioe ) {} // load and save may throw IOExceptions.
* <PRE>
* @author Carsten Knudsen
* @version 1.0
**/
public class Serialization {
    /**
    * The class Serialization only has a private constructor
    * to prevent instantiation.
    * Use the class through its static methods.
    **/
    private Serialization() {
    } // constructor

    /**
    * Saves the serializable object o to the named file.
    **/
    public static void save( Serializable o, String name ) throws IOException {
    save( o, new File( name ) );
    } // save

    /**
    * Saves the serializable object o to the File object.
    **/
    public static void save( Serializable o, File file ) throws IOException {
    ObjectOutputStream out = new ObjectOutputStream( new FileOutputStream( file ) );
    out.writeObject( o );
    out.close();
    } // save

    /**
    * Loads a serializable object from the named file.
    **/
    public static Serializable load( String name ) throws IOException, ClassNotFoundException {
    return load( new File( name ) );
    } // save

    /**
    * Loads a serializable object from the File object.
    **/
    public static Serializable load( File file ) throws IOException, ClassNotFoundException {
    ObjectInputStream in = new ObjectInputStream( new FileInputStream( file ) );
    Serializable o = (Serializable)in.readObject();
    in.close();
    return o;
    } // load

    /**
    * The method makes a deep clone of the serializable object o by
    * sending it through piped streams.
    **/
    public static Serializable deepclone( final Serializable o )
    throws IOException, ClassNotFoundException {
    final PipedOutputStream pipeout = new PipedOutputStream();
    PipedInputStream pipein = new PipedInputStream( pipeout );
    Thread writer = new Thread() {
        public void run() {
            ObjectOutputStream out = null;
            try {
            out = new ObjectOutputStream( pipeout );
            out.writeObject( o );
            } // try
            catch( IOException e ) {
            } // catch
            finally {
            try {
                out.close();
            } // try
            catch( Exception e ) {
            } // catch
            } // finally
        } // run
        };
    writer.start();
    ObjectInputStream in = new ObjectInputStream( pipein );
    Serializable a = (Serializable)in.readObject();
    in.close();
    return a;
    } // deepclone

    /**
    *
    **/
    public static File loadFile() {
    final String ext = "ser";
    JFileChooser fileChooser = new JFileChooser( new File( System.getProperty( "user.dir" ) ) );
    fileChooser.setApproveButtonText( "Load" );
    fileChooser.setFileFilter( new javax.swing.filechooser.FileFilter () {
        public boolean accept( File file ) {
        String fileName = file.getName();
        if ( fileName.endsWith( "." + ext ) ) return true;
        else return false;
        } // accept
        public String getDescription() {
        return "Serialized. (*.ser)";
        } // getDescription
    });
    int result = fileChooser.showOpenDialog( null );
    if ( result == JFileChooser.APPROVE_OPTION ) {
        return fileChooser.getSelectedFile();
    } // if
    else {
        return null;
    } // else
    } // loadFile

    /**
    *
    **/
    public static File saveFile() {
    final String ext = "ser";
    JFileChooser fileChooser = new JFileChooser( new File( System.getProperty( "user.dir" ) ) );
    fileChooser.setApproveButtonText( "Save" );
    fileChooser.setFileFilter( new javax.swing.filechooser.FileFilter () {
        public boolean accept( File file ) {
        String fileName = file.getName();
        if ( fileName.endsWith( "." + ext ) ) return true;
        else return false;
        } // accept
        public String getDescription() {
        return "Serialized. (*.ser)";
        } // getDescription
    });
    int result = fileChooser.showSaveDialog( null );
    if ( result == JFileChooser.APPROVE_OPTION ) {
        return fileChooser.getSelectedFile();
    } // if
    else {
        return null;
    } // else
    } // saveFile

} // Serialization
Avatar billede carstenknudsen Nybegynder
14. maj 2002 - 14:46 #12
Fandt lige følgende der dog også kræver
at du ikke bruger arrays etc.
Du kan ændre access fra protected to private
og så får du en mere elegant løsning
for simple kloningsproblemer, men bemærk
at du selv i dette eksempel står for al
initialisering!

class MyClass implements Cloneable {
        public MyClass() {
        }
        public Object clone() {
            Cloneable theClone = new MyClass();
            // Initialize theClone.
            return theClone;
        }
    }
Avatar billede aslan Nybegynder
14. maj 2002 - 14:47 #13
Takker jeg studere den nærmere!
Avatar billede Ny bruger Nybegynder

Din løsning...

Tilladte BB-code-tags: [b]fed[/b] [i]kursiv[/i] [u]understreget[/u] Web- og emailadresser omdannes automatisk til links. Der sættes "nofollow" på alle links.

Loading billede Opret Preview
Kategori
Kurser inden for grundlæggende programmering

Log ind eller opret profil

Hov!

For at kunne deltage på Computerworld Eksperten skal du være logget ind.

Det er heldigvis nemt at oprette en bruger: Det tager to minutter og du kan vælge at bruge enten e-mail, Facebook eller Google som login.

Du kan også logge ind via nedenstående tjenester