JavaRush /مدونة جافا /Random-AR /المحصلون والمستوطنون

المحصلون والمستوطنون

نشرت في المجموعة
مرحبًا! لقد تعلمت في المحاضرات السابقة كيفية إنشاء فصولك الدراسية الكاملة الخاصة بك، مع الحقول والأساليب. هذا تقدم جدي، أحسنت! ولكن الآن يجب أن أخبرك بحقيقة غير سارة. لم ننشئ فصولنا بشكل صحيح تمامًا! لماذا؟ للوهلة الأولى، لا توجد أخطاء في هذا الفصل:
public class Cat {

   public String name;
   public int age;
   public int weight;

   public Cat(String name, int age, int weight) {
       this.name = name;
       this.age = age;
       this.weight = weight;
   }

   public Cat() {
   }

   public void sayMeow() {
       System.out.println("Meow!");
   }
}
في الواقع، هناك. تخيل أنك أثناء جلوسك في العمل كتبت فصلًا كهذا Catيشير إلى القطط. وذهب إلى المنزل. أثناء غيابك، جاء مبرمج آخر للعمل، وأنشأ فصله الخاص Main، حيث بدأ في استخدام الفصل الذي كتبته Cat.
public class Main {

   public static void main(String[] args) {

       Cat cat = new Cat();
       cat.name = "";
       cat.age = -1000;
       cat.weight = 0;
   }
}
لا يهم لماذا فعل ذلك أو كيف حدث: ربما كان الشخص متعبًا أو لم يحصل على قسط كافٍ من النوم. شيء آخر مهم: فصلنا الحالي Catيسمح لك بتعيين قيم مجنونة للحقول. ونتيجة لذلك، يحتوي البرنامج على كائنات بحالة غير صحيحة، مثل هذه القطة التي يبلغ عمرها -1000 عام. ما الخطأ الذي ارتكبناه في النهاية؟ عندما أنشأنا الفصل، كشفنا عن بياناته. الحقول name، ageوهي weightفي المجال العام. يمكن الوصول إليها في أي مكان في البرنامج: ما عليك سوى إنشاء كائن Cat- وهذا كل شيء، يمكن لأي مبرمج الوصول إلى بياناته مباشرة من خلال عامل التشغيل " ."
Cat cat = new Cat();
cat.name = "";
هنا نصل مباشرة إلى الحقل nameونحدد قيمته. نحن بحاجة إلى حماية بياناتنا بطريقة أو بأخرى من التدخل الخارجي غير الصحيح. ما هو المطلوب لهذا؟ أولاً، يجب وضع علامة على كافة متغيرات المثيل (الحقول) باستخدام المُعدِّل private. الخاص هو معدل الوصول الأكثر صرامة في Java. إذا كنت تستخدمه، فلن يكون من الممكن الوصول إلى حقول الفصل Catخارجه.
public class Cat {

   private String name;
   private int age;
   private int weight;

   public Cat(String name, int age, int weight) {
       this.name = name;
       this.age = age;
       this.weight = weight;
   }

   public Cat() {
   }

   public void sayMeow() {
       System.out.println("Meow!");
   }
}

public class Main {

   public static void main(String[] args) {

       Cat cat = new Cat();
       cat.name = "";//error! The name field in the Cat class has private access!
   }
}
يرى المترجم هذا وينتج خطأ على الفور. الآن يبدو أن الحقول محمية. لكن اتضح أن الوصول إليها مغلق "بإحكام": لا يستطيع البرنامج حتى الحصول على وزن قطة موجودة، إذا لزم الأمر. وهذا أيضًا ليس خيارًا: في هذا النموذج يكون استخدام فصلنا مستحيلًا عمليًا. من الناحية المثالية، نحتاج إلى السماح بنوع من الوصول المحدود إلى البيانات:
  • يجب أن يكون المبرمجون الآخرون قادرين على إنشاء الكائناتCat
  • يجب أن يكونوا قادرين على قراءة البيانات من الكائنات الموجودة بالفعل (على سبيل المثال، الحصول على اسم أو عمر قطة موجودة بالفعل)
  • يجب أن يكون من الممكن أيضًا تعيين قيم الحقول. ولكن في نفس الوقت - القيم الصحيحة فقط. يجب حماية أغراضنا من الأشياء غير الصحيحة (ليس "العمر = -1000 سنة" وما شابه).
قائمة المتطلبات لائقة! ولكن في الواقع ، كل هذا يمكن تحقيقه بسهولة باستخدام أساليب خاصة - الحروف والأدوات .
المرابطون والمقيمون - 2
يأتي الاسم من الكلمة الإنجليزية " get " - " receive " (أي "طريقة الحصول على قيمة الحقل") و set - " set " (أي "طريقة تحديد قيمة الحقل"). دعونا نرى كيف تبدو باستخدام صفنا كمثال Cat:
public class Cat {

   private String name;
   private int age;
   private int weight;

   public Cat(String name, int age, int weight) {
       this.name = name;
       this.age = age;
       this.weight = weight;
   }

   public Cat() {
   }

   public void sayMeow() {
       System.out.println("Meow!");
   }

   public String getName() {
       return name;
   }

   public void setName(String name) {
       this.name = name;
   }

   public int getAge() {
       return age;
   }

   public void setAge(int age) {
       this.age = age;
   }

   public int getWeight() {
       return weight;
   }

   public void setWeight(int weight) {
       this.weight = weight;
   }
}
كما ترون، كل شيء بسيط للغاية :) غالبًا ما تتكون أسمائهم من كلمة get/set + اسم المجال المسؤول عنه. على سبيل المثال، تقوم إحدى الطرق getWeight()بإرجاع قيمة حقل weightالكائن الذي تم استدعاؤها من أجله. وهذا ما يبدو عليه في البرنامج:
public class Main {

   public static void main(String[] args) {

       Cat barsik = new Cat("Barsik", 5, 4);
       String barsikName = barsik.getName();
       int barsikAge = barsik.getAge();
       int barsikWeight = barsik.getWeight();

       System.out.println("Cat name: " + barsikName);
       System.out.println("Cat's age: " + barsikAge);
       System.out.println("Weight of the cat: " + barsikWeight);
   }
}
إخراج وحدة التحكم:

Name кота: Барсик
Возраст кота: 5
Вес кота: 4
الآن من فئة أخرى ( Main) هناك إمكانية الوصول إلى الحقول Cat، ولكن فقط من خلال الحروف . برجاء ملاحظة أن الحروف لديها معدل وصول public، مما يعني أنه يمكن الوصول إليها من أي مكان في البرنامج. ماذا عن تعيين القيم؟ أساليب الضبط هي المسؤولة عن هذا
public void setName(String name) {
   this.name = name;
}
عملهم، كما ترون، هو أيضا بسيط. نحن نستدعي طريقة setName()على كائن Cat، ونمرر لها سلسلة كوسيطة، ويتم تعيين هذه السلسلة إلى حقل nameكائننا.
public class Main {

   public static void main(String[] args) {

       Cat barsik = new Cat("Barsik", 5, 4);

       System.out.println("The original name of the cat is " + barsik.getName());
       barsik.setName("Basil");
       System.out.println("The new name of the cat -" + barsik.getName());
   }
}
استخدمنا هنا كلا من الحروف والمستوطنين. أولاً، باستخدام أداة getter، تلقينا وعرضنا الاسم الأولي للقطة في وحدة التحكم. بعد ذلك، باستخدام أداة الضبط، nameتم تعيين قيمة جديدة لحقلها - "فاسيلي". وبعد ذلك، باستخدام أداة getter، حصلنا على الاسم مرة أخرى للتحقق مما إذا كان قد تغير بالفعل. إخراج وحدة التحكم:

Изначальное Name кота — Барсик
Новое Name кота — Васorй
يبدو أن ما هو الفرق؟ يمكننا أيضًا تعيين قيم غير صحيحة لحقول الكائنات، حتى لو كان لدينا أدوات ضبط:
public class Main {

   public static void main(String[] args) {

       Cat barsik = new Cat("Barsik", 5, 4);
       barsik.setAge(-1000);

       System.out.println("Age of Barsik -" + barsik.getAge() + " years");
   }
}
إخراج وحدة التحكم:

Возраст Барсика — -1000 лет
الفرق هو أن أداة الضبط هي طريقة كاملة . وبطريقة ما، على عكس الحقل، يمكنك تضمين منطق التحقق الذي تحتاجه لمنع القيم غير المقبولة. على سبيل المثال، يمكنك بسهولة تعطيل تعيين رقم سالب كعمر:
public void setAge(int age) {
   if (age >= 0) {
       this.age = age;
   } else {
       System.out.println("Error! Age cannot be negative!");
   }
}
والآن يعمل الكود الخاص بنا بشكل صحيح!
public class Main {

   public static void main(String[] args) {

       Cat barsik = new Cat("Barsik", 5, 4);
       barsik.setAge(-1000);

       System.out.println("Age of Barsik -" + barsik.getAge() + " years");
   }
}
إخراج وحدة التحكم:

Ошибка! Возраст не может быть отрицательным числом!
Возраст Барсика — 5 лет
يوجد قيد داخل أداة الضبط، وهو يحمي من محاولات ضبط البيانات غير الصحيحة. بقي عمر بارسيك دون تغيير. يجب دائمًا إنشاء الحروف والمستوطنين. حتى لو لم يكن لحقولك أي قيود على القيم المحتملة، فلن يكون هناك أي ضرر منها. تخيل موقفًا: أنت وزملائك تكتبون برنامجًا معًا. لقد قمت بإنشاء فصل دراسي Catيحتوي على حقول عامة، ويستخدمها جميع المبرمجين كما يريدون. ثم في أحد الأيام الجميلة يخطر ببالك: "اللعنة، عاجلاً أم آجلاً قد يقوم شخص ما عن طريق الخطأ بتعيين رقم سالب لمتغير weight! نحن بحاجة إلى إنشاء مستوطنين وجعل جميع الحقول خاصة! تقوم بإنشائها، وتنكسر جميع التعليمات البرمجية التي كتبها زملائك على الفور. بعد كل شيء، لقد كتبوا بالفعل مجموعة من التعليمات البرمجية حيث تمكنوا من الوصول إلى الحقول Catمباشرة.
cat.name = "Hippopotamus";
والآن أصبحت الحقول خاصة وينتج عن المترجم مجموعة من الأخطاء!
cat.name = "Hippopotamus";//error! The name field of the Cat class has private access!
في مثل هذه الحالة، سيكون من الأفضل إخفاء الحقول وإنشاء الحروف المحرفية من البداية . سيستخدمها جميع زملائك، وإذا اتضح لك متأخرًا أنك بحاجة إلى تحديد قيم الحقول، فستقوم ببساطة بإضافة شيك داخل أداة الضبط. ولن يكسر أحد الكود المكتوب بالفعل. بالطبع، إذا كنت تريد الوصول للقراءة فقط إلى حقل معين، فيمكنك إنشاء أداة getter واحدة له. "الخارج"، أي خارج صفك، يجب أن يكون الوصول إلى الأساليب فقط ممكنًا. يجب أن تكون مخفية البيانات.
المرابطون والمقيمون - 4
ويمكن إجراء تشبيه مع الهاتف المحمول. تخيل أنه بدلاً من تشغيل الهاتف المحمول العادي، تم إعطاؤك هاتفًا بغطاء مفتوح، حيث توجد جميع الأسلاك والدوائر وما إلى ذلك. بارزة. الهاتف يعمل: إذا حاولت جاهدًا التلاعب بالرسوم البيانية، فقد تتمكن حتى من إجراء مكالمة. لكن من المحتمل أن تكسرها. وبدلاً من ذلك، توفر لك الشركة المصنعة واجهة: يقوم العميل ببساطة بطلب الأرقام المطلوبة، والضغط على الزر الأخضر بسماعة الهاتف، وتبدأ المكالمة. ولا يهتم بما يجري بالداخل من دوائر وأسلاك وكيفية قيامها بمهمتها. في هذا المثال، تتمتع الشركة بإمكانية وصول محدودة إلى "البيانات الداخلية" للهاتف وتركت الواجهة (الطرق) فقط في الخارج. ونتيجة لذلك، سيحصل العميل على ما يريده (إجراء مكالمة) وبالتأكيد لن يكسر أي شيء بداخله.
تعليقات
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION