دالة clone()
جزء من قسم البرمجة كائنية التوجه في رحلة Java على Coddy. الدرس 43 من 87.
تنشئ clone() method نسخة من object. لاستخدامها، يجب أن implement class الخاص بك الواجهة Cloneable وأن تُعيد تعريف method clone() من class Object.
public class Person implements Cloneable {
private String name;
private int age;
public Person(String name, int age) {
this.name = name;
this.age = age;
}
@Override
public Person clone() {
try {
return (Person) super.clone();
} catch (CloneNotSupportedException e) {
throw new RuntimeException(e);
}
}
}يمكنك الآن إنشاء نسخ مستقلة من الكائنات:
Person original = new Person("Alice", 25);
Person copy = original.clone();
// copy هو كائن منفصل بنفس القيمافتراضيًا، ينفّذ clone() نسخًا سطحيًا، ما يعني أنه ينسخ القيم البدائية والمراجع. إذا كان object الخاص بك يحتوي على objectات أخرى باعتبارها fields، فسوف يشير كلٌّ من original وclone إلى objectات متداخلة نفسها. للحصول على نسخ مستقلة حقًا تحتوي على objectات متداخلة، تحتاج إلى implement نسخًا عميقًا عن طريق استنساخ تلك objectات المتداخلة أيضًا داخل method clone() الخاصة بك.
التحدي
سهللننشئ نظامًا لإدارة المستندات يوضّح استنساخ الكائنات. ستنشئ فئة Document يمكن استنساخها لإنشاء نسخ مستقلة، مما يتيح للمستخدمين تكرار المستندات مع الحفاظ على المستند الأصلي دون تغيير.
ستنظّم التعليمات البرمجية في ملفين:
Document.java: أنشئ فئة تمثّل مستندًا وتدعم الاستنساخ. يحتوي Document على ثلاثة حقول private:title(String)، وauthor(String)، وversion(int). أضف constructor لتهيئة جميع الحقول، وأضف getter methods لكل منها. أضف أيضًا method باسمsetVersion(int version)لتحديث رقم الإصدار.اجعل فئة Document تنفّذ interface
Cloneable، وأعد تعريف methodclone()لإرجاعDocument. عالجCloneNotSupportedExceptionداخل method من خلال تغليفه داخلRuntimeException.أعد تعريف
toString()لإرجاع:Document[title=X, author=Y, version=Z]حيث تمثّل X وY وZ قيم الحقول الفعلية.Main.java: فعّل فئة Document من خلال إنشاء مستند واستنساخه. ستتلقى ثلاثة inputs: عنوانًا (String)، وauthor (String)، ورقم إصدار (int).أنشئ Document أصليًا باستخدام هذه القيم، ثم استنسخه لإنشاء نسخة. بعد الاستنساخ، عدّل version الخاص بالنسخة بزيادته بمقدار 1 باستخدام
setVersion(). يوضّح هذا أن النسخة المستنسخة مستقلة حقًا عن المستند الأصلي.اطبع ثلاثة أسطر:
Original:متبوعًا بـ toString() الخاص بالمستند الأصليClone:متبوعًا بـ toString() الخاص بالمستند المستنسخIndependent:متبوعًا بـtrueأوfalseللإشارة إلى ما إذا كان المستند الأصلي والنسخة المستنسخة كائنين مختلفين (استخدم مقارنة!=)
ستتلقى ثلاثة inputs: عنوان المستند (String)، واسم author (String)، ورقم الإصدار (int).
لاحظ أنه بعد تعديل version الخاص بالنسخة المستنسخة، يظل المستند الأصلي دون تغيير. يثبت هذا أن clone() أنشأ نسخة مستقلة حقًا!
جرّب بنفسك
import java.util.Scanner;
class Main {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
// قراءة المدخلات
String title = scanner.nextLine();
String author = scanner.nextLine();
int version = scanner.nextInt();
// TODO: إنشاء Document أصلي باستخدام قيم المدخلات
// TODO: استنساخ المستند الأصلي لإنشاء نسخة
// TODO: تعديل إصدار النسخة المستنسخة بزيادته بمقدار 1
// TODO: طباعة "Original: " متبوعة بالمستند الأصلي
// TODO: طباعة "Clone: " متبوعة بالمستند المستنسخ
// TODO: طباعة "Independent: " متبوعة بـ true/false (التحقق مما إذا كان original != clone)
}
}يتضمن هذا الدرس اختبارًا قصيرًا. ابدأ الدرس للإجابة عليه وتتبّع تقدمك.
جميع دروس البرمجة كائنية التوجه
1أساسيات الـ OOP
الملفات الخارجيةمقدمة في الـ OOPالفئات (Classes) مقابل الكائنات (Objects)الكلمة المفتاحية thisالدوال (Methods)الحقول (Attributes)دالة البناء (Constructor)تعدد أشكال دالة البناء (Constructor Overloading)مراجعة - آلة حاسبة بسيطة4الوراثة
الوراثة الأساسية (extends)الكلمة المفتاحية superإعادة تعريف الدوال (@Override)تسلسل المنشئات (Constructor Chaining)كلاس Objectالوراثة الأحادية ومتعددة المستوياتلماذا لا توجد وراثة متعددة للكلاساتمراجعة - هيكلية الموظفين7الدوال الخاصة وفئة Object
دالة toString()equals() و hashCode()دالة clone()compareTo() و Comparableواجهة Comparatorمراجعة - الترتيب المخصص2محددات الوصول والتغليف
نظرة عامة على مستويات الوصولدوال Getter و Setterإخفاء البياناتالكلمة المفتاحية finalمراجعة - مدير الحساب البنكي5تعدد الأشكال (Polymorphism)
أساسيات الـ Method Overloadingالـ Method Overriding (في وقت التشغيل)الـ Upcasting والـ Downcastingمعامل الـ instanceofالفئات والدوال المجردة (Abstract)مراجعة - حاسبة الأشكال8مفاهيم OOP المتقدمة
الـ Composition مقابل الـ Inheritanceالـ Aggregation مقابل الـ Compositionالفئات الداخلية والمتداخلة والمجهولة (Inner, Nested & Anonymous)الـ Enums ودوالهاالـ Records (Java 16+)الـ Sealed Classes (Java 17+)11أنماط التصميم - الجزء الأول
مقدمة في أنماط التصميمنمط Singletonنمط Factoryنمط Builderنمط Observerنمط Strategy3خصائص الفئة والعضو الساكن
المتغيرات الخاصة بالكائن مقابل المتغيرات الساكنةالدوال الساكنةالكتل البرمجية الساكنةالثوابت (static final)ملخص - العداد والأدوات المساعدة6الواجهات (Interfaces) والأصناف المجردة (Abstract Classes)
مقدمة في الواجهات (Interfaces)تنفيذ الواجهات (Interfaces)تنفيذ واجهات متعددةالـ Default و Static في الواجهاتالأصناف المجردة مقابل الواجهاتالواجهات الوظيفية (Functional Interfaces)مراجعة - نظام الدفع9الأنواع العامة (Generics)
مقدمة في الأنواع العامةالأصناف العامة (Generic Classes)الدوال العامة (Generic Methods)معاملات الأنواع المقيدةالرموز البديلة (?, extends, super)مراجعة - الحاويات العامة12أنماط التصميم - الجزء الثاني
نمط الأمرنمط المحولنمط المزيننمط طريقة القالبنمط الحالةنمط التركيبنمط المكررتدرّب بنفسك: مترجم Java عبر الإنترنت