Loading...

Ссылкалык типтер жана объекттерди көчүрүү

 

Класстын объекттери менен иштөөдө алардын бардыгы шилтеме типтерин билдирерин, башкача айтканда, алар эстутумда жайгашкан кандайдыр бир объектти көрсөтөөрүн эске алуу керек. Биз туш болушу мүмкүн болгон кыйынчылыктарды түшүнүү үчүн, бир мисал карап көрөлү:

public class Program{

     

    public static void main(String[] args) {

         

        Person tom = new Person("Tom", 23);

        tom.display();      // Person Tom

        Person bob = tom;

        bob.setName("Bob");

        tom.display();      // Person Bob

    }

}

class Person{

    private String name;

    private int age;

    

    Person(String name, int age){

        this.name=name;

        this.age=age;

    }

    void setName(String name){

        this.name = name;

    }

    void setAge(int age){

        this.age = age;

    }

    void display(){

        System.out.printf("Person Name: %s \n", name);

    }

}

Бул жерде биз эки Person объектисин түзүп, бирин экинчисине дайындайбыз. Бирок биз боб объектисин гана өзгөрткөнүбүз менен, Том объектиси да аны менен өзгөрөт. Анткени дайындоодон кийин алар эстутумдагы ошол эле аймакты көрсөтөт, анда Person объектиси жана анын талаалары жөнүндө чыныгы маалыматтар сакталат.

Бул көйгөйдү болтурбоо үчүн, сиз боб өзгөрмөсүнө өзүнчө объект түзүшүңүз керек, мисалы, клон ыкмасын колдонуу:

class Person implements Cloneable{

    private String name;

    private int age;

    

    Person(String name, int age){

        this.name=name;

        this.age=age;

    }

    void setName(String name){

        this.name = name;

    }

    void setAge(int age){

        this.age = age;

    }

    void display(){

        System.out.printf("Person %s \n", name);

    }

    

    public Person clone() throws CloneNotSupportedException{

     

        return (Person) super.clone();

    }

}

Клондоштурууну ишке ашыруу үчүн Person classes klondoo ykmasyn anyktagan Cloneable interfacein колдонушу керек. Бул ыкманы ишке ашаруу жон гана ата-эне классындагы клондук методого чакырууну кайрат - башкача айтканда, Person'ga chigaruu change Object classes.

 

Koshumchalai ketsek, class CloneNotSupportedException ыргытышы керек, ал ыргытуучу оператор аркылуу аныкталат.

 

Андан кийин, бул ыкманы чакыруу менен, биз кочуруп алабыз:

 

try{

    Person tom = new Person("Tom", 23);

    Person bob = tom.clone();

    bob.setName("Bob");

    tom.display();      // Person Tom

}

catch(CloneNotSupportedException ex){

                 

    System.out.println("Clonable not implemented");

}

Бирок, бул ыкма толук эмес көчүрмөнү аткарат жана клондолгон объектте татаал объекттер жок болсо ылайыктуу. Мисалы, китеп классында төмөнкү аныктама бар дейли:

class Book implements Cloneable{

 

    private String name;

    private Author author;

    

    public void setName(String n){ name=n;}

    public String getName(){ return name;}

    

    public void setAuthor(String n){ author.setName(n);}

    public String getAuthor(){ return author.getName();}

 

    Book(String name, String author){

        

        this.name = name;

        this.author = new Author(author);

    }

    

    public String toString(){

        

        return "Книга '" + name + "' (автор " +  author + ")";

    }

    

    public Book clone() throws CloneNotSupportedException{

    

        return (Book) super.clone();

    }

}

 

class Author{

 

    private String name;

    

    public void setName(String n){ name=n;}

    public String getName(){ return name;}

    

    public Author(String name){

    

        this.name=name;

    }

}

Эгер китептин авторун өзгөртүүгө аракет кылсак, ийгиликсиз болобуз:

try{

    Book book = new Book("War and Peace", "Leo Tolstoy");

    Book book2 = book.clone();

    book2.setAuthor("Ivan Turgenev");

    System.out.println(book.getAuthor());

}

catch(CloneNotSupportedException ex){

        

    System.out.println("Cloneable not implemented");

}

Бул учурда, book жана book2 өзгөрмөлөрү эстутумдагы ар кандай объекттерди көрсөтсө да, бул объекттер баары бир Author объектисин көрсөтүп турат.

Жана бул учурда, биз толук көчүрмөсүн аткаруу керек. Бул үчүн, сиз Author классы үчүн клон ыкмасын аныкташыңыз керек:

class Author implements Cloneable{

 

    // остальной код класса

    

    public Author clone() throws CloneNotSupportedException{

    

        return (Author) super.clone();

    }

}

Анан китеп классындагы клон ыкмасын төмөнкүдөй оңдоңуз:

public Book clone() throws CloneNotSupportedException{

    

    Book newBook = (Book) super.clone();

    newBook.author=(Author) author.clone();

    return newBook;

}