CodeGym /وبلاگ جاوا /Random-FA /گیرنده و تنظیم کننده
John Squirrels
مرحله
San Francisco

گیرنده و تنظیم کننده

در گروه منتشر شد
سلام! در سخنرانی‌های قبلی، قبلاً یاد گرفته‌اید که چگونه کلاس‌های کامل خود را با روش‌ها و فیلدها اعلام کنید. در درس امروز در مورد Getters و Setter در جاوا صحبت خواهیم کرد. این پیشرفت جدی است، آفرین! اما اکنون باید یک حقیقت ناخوشایند را به شما بگویم. کلاس هایمان را درست اعلام نکردیم! چرا؟ در نگاه اول، کلاس زیر هیچ اشتباهی ندارد:
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 را برای نشان دادن گربه ها بنویسید. و بعد میری خونه در حالی که شما رفته اید، برنامه نویس دیگری سر کار می آید. او کلاس اصلی خود را ایجاد می کند ، جایی که شروع به استفاده از کلاس Cat شما می کند .
public class Main {

   public static void main(String[] args) {

       Cat cat = new Cat();
       cat.name = "";
       cat.age = -1000;
       cat.weight = 0;
   }
}
مهم نیست چرا این کار را کرد و چگونه اتفاق افتاد (شاید آن مرد خسته باشد یا به اندازه کافی نخوابیده باشد). چیز دیگری مهم است: کلاس Cat فعلی ما به فیلدها اجازه می دهد مقادیر کاملاً دیوانه کننده ای نسبت داده شوند. در نتیجه، برنامه دارای اشیایی با حالت نامعتبر است (مانند این گربه که -1000 سال سن دارد). پس چه خطایی در هنگام اعلام کلاس خود مرتکب شدیم؟ ما داده های کلاس خود را افشا کردیم. فیلدهای نام، سن و وزن عمومی هستند. آنها را می توان در هر جایی از برنامه در دسترس قرار داد: به سادگی یک شی Cat ایجاد کنید و هر برنامه نویسی از طریق عملگر نقطه ( . ) به داده های آن دسترسی مستقیم دارد.
Cat cat = new Cat();
cat.name = "";
در اینجا ما مستقیماً به فیلد نام دسترسی پیدا می کنیم و مقدار آن را تنظیم می کنیم. ما باید به نحوی از داده های خود در برابر تداخل نامناسب خارجی محافظت کنیم. برای این کار چه نیازی داریم؟ ابتدا، تمام متغیرهای نمونه (فیلدها) باید با اصلاح کننده خصوصی علامت گذاری شوند. Private سخت ترین اصلاح کننده دسترسی در جاوا است. پس از انجام این کار، فیلدهای کلاس 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 Cat class's name field is private!
   }
}
کامپایلر این را می بیند و بلافاصله یک خطا ایجاد می کند. اکنون زمینه ها به نوعی محافظت شده اند. اما به نظر می رسد که ما دسترسی را به شدت قطع کرده ایم: شما نمی توانید وزن یک گربه موجود را در برنامه دریافت کنید، حتی اگر نیاز داشته باشید. این نیز یک گزینه نیست. همانطور که هست، کلاس ما اساسا غیر قابل استفاده است. در حالت ایده آل، باید به نوعی دسترسی محدود اجازه دهیم:
  • برنامه نویسان دیگر باید بتوانند اشیاء Cat را ایجاد کنند
  • آنها باید بتوانند داده ها را از اشیاء موجود بخوانند (به عنوان مثال، نام یا سن یک گربه موجود را دریافت کنند)
  • همچنین باید امکان اختصاص مقادیر فیلد وجود داشته باشد. اما در انجام این کار، فقط مقادیر معتبر باید مجاز باشند. اشیاء ما باید از مقادیر نامعتبر محافظت شوند (به عنوان مثال سن = -1000 و غیره).
این یک لیست مناسب از الزامات است! در واقع همه اینها به راحتی با روش های خاصی به نام گیر و ستتر به دست می آید.
گیرنده و تنظیم کننده - 2
این نام ها از "get" (یعنی "روش برای بدست آوردن مقدار یک فیلد") و "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() مقدار فیلد وزن را برای شیئی که فراخوانی شده است برمی گرداند. در اینجا چگونه به نظر می رسد در یک برنامه:
public class Main {

   public static void main(String[] args) {

       Cat smudge = new Cat("Smudge", 5, 4);
       String smudgeName = smudge.getName();
       int smudgeAge = smudge.getAge();
       int smudgeWeight = smudge.getWeight();

       System.out.println("Cat's name: " + smudgeName);
       System.out.println("Cat's age: " + smudgeAge);
       System.out.println("Cat's weight: " + smudgeWeight);
   }
}
خروجی کنسول:
Cat's name: Smudge
Cat's age: 5
Cat's weight: 4
اکنون یک کلاس دیگر ( Main ) می تواند به فیلدهای Cat دسترسی داشته باشد ، اما فقط از طریق دریافت کننده. توجه داشته باشید که دریافت کننده ها دارای اصلاح کننده دسترسی عمومی هستند، یعنی از هر کجای برنامه در دسترس هستند. اما در مورد تخصیص مقادیر چیست؟ این همان چیزی است که روش های تنظیم کننده برای آن هستند
public void setName(String name) {
   this.name = name;
}
همانطور که می بینید، آنها نیز ساده هستند. متد setName() را روی یک شی Cat فراخوانی می کنیم ، رشته ای را به عنوان آرگومان ارسال می کنیم و رشته به فیلد نام شی اختصاص می یابد.
public class Main {

   public static void main(String[] args) {

       Cat smudge = new Cat("Smudge", 5, 4);

       System.out.println("Cat's original name: " + smudge.getName());
       smudge.setName("Mr. Smudge");
       System.out.println("Cat's new name: " + smudge.getName());
   }
}
در اینجا ما از هر دو گیرنده و تنظیم کننده استفاده می کنیم. ابتدا از یک گیرنده برای دریافت و نمایش نام اصلی گربه استفاده می کنیم. سپس، از یک تنظیم کننده برای اختصاص یک نام جدید ("Mr. Smudge") استفاده می کنیم. و سپس یک بار دیگر از گیرنده برای به دست آوردن نام (برای بررسی اینکه آیا واقعاً تغییر کرده است) استفاده می کنیم. خروجی کنسول:
Cat's original name: Smudge
Cat's new name: Mr. Smudge
پس چه فرقی دارد؟ ما همچنان می‌توانیم مقادیر نامعتبری را به فیلدها اختصاص دهیم حتی اگر تنظیم‌کننده‌ها داشته باشیم:
public class Main {

   public static void main(String[] args) {

       Cat smudge = new Cat("Smudge", 5, 4);
       smudge.setAge(-1000);

       System.out.println("Smudge's age: " + smudge.getAge());
   }
}
خروجی کنسول:
Smudge's age: -1000 years
تفاوت این است که ستر یک روش تمام عیار است. و برخلاف یک فیلد، یک متد به شما امکان می‌دهد منطق تأیید لازم برای جلوگیری از مقادیر غیرقابل قبول را بنویسید. به عنوان مثال، به راحتی می توانید از اختصاص یک عدد منفی به عنوان سن جلوگیری کنید:
public void setAge(int age) {
   if (age >= 0) {
       this.age = age;
   } else {
       System.out.println("Error! Age can't be negative!");
   }
}
و اکنون کد ما به درستی کار می کند!
public class Main {

   public static void main(String[] args) {

       Cat smudge = new Cat("Smudge", 5, 4);
       smudge.setAge(-1000);

       System.out.println("Smudge's age: " + smudge.getAge());
   }
}
خروجی کنسول:
Error! Age can't be negative!
Smudge's age: 5 years
در داخل تنظیم کننده، محدودیتی ایجاد کردیم که ما را از تلاش برای تنظیم داده های نامعتبر محافظت می کرد. سن Smudge تغییر نکرد. همیشه باید گیرنده و ستتر ایجاد کنید. حتی اگر محدودیتی در مورد مقادیری که فیلدهای شما می توانند داشته باشند وجود نداشته باشد، این روش های کمکی هیچ ضرری ندارند. وضعیت زیر را تصور کنید: شما و همکارانتان در حال نوشتن یک برنامه با هم هستید. شما یک کلاس Cat با فیلدهای عمومی ایجاد می کنید. همه برنامه نویسان هر طور که می خواهند از آنها استفاده می کنند. و سپس یک روز خوب متوجه می‌شوید: "دیگه، دیر یا زود ممکن است شخصی به طور تصادفی یک عدد منفی به وزن اختصاص دهد! ما باید تنظیم‌کننده‌ها را ایجاد کنیم و همه فیلدها را خصوصی کنیم!" شما این کار را انجام می دهید و بلافاصله تمام کدهای نوشته شده توسط همکارانتان را می شکنید. از این گذشته، آنها قبلاً یک سری کد نوشته اند که مستقیماً به فیلدهای Cat دسترسی دارد.
cat.name = "Behemoth";
و حالا فیلدها خصوصی هستند و کامپایلر یک سری خطا منتشر می کند!
cat.name = "Behemoth";//error! The Cat class's name field is private!
در این صورت بهتر است از همان ابتدا فیلدها را مخفی کنید و گیر و ستتر ایجاد کنید. همه همکاران شما از آنها استفاده می کردند. و اگر با تأخیر متوجه شدید که باید مقادیر فیلد را به نحوی محدود کنید، می‌توانید چک را در داخل تنظیم‌کننده بنویسید. و کد هیچ کس شکسته نمی شود. البته، اگر می‌خواهید دسترسی به یک فیلد فقط «فقط خواندنی» باشد، می‌توانید فقط یک گیرنده برای آن ایجاد کنید. فقط متدها باید به صورت خارجی (یعنی خارج از کلاس شما) در دسترس باشند. داده ها باید پنهان شوند. می توانیم مقایسه ای با تلفن همراه داشته باشیم. تصور کنید که به جای تلفن همراه معمولی بسته، یک تلفن با قاب باز، با انواع سیم ها، مدارها و غیره بیرون زده به شما داده شده است. قادر به برقراری تماس اما احتمالاً آن را می شکنند.
گیرنده و تنظیم کننده - 3
در عوض، سازنده یک رابط به شما می دهد: کاربر به سادگی اعداد صحیح را وارد می کند، دکمه سبز رنگ تماس را فشار می دهد و تماس شروع می شود. برایش مهم نیست که در داخل مدارها و سیم‌ها چه اتفاقی می‌افتد، یا اینکه چگونه کارشان را انجام می‌دهند. در این مثال، شرکت دسترسی به "داخل" گوشی (داده ها) را محدود کرده و فقط یک رابط (روش ها) را در معرض نمایش قرار می دهد. در نتیجه، کاربر به چیزی که می‌خواست (قابلیت برقراری تماس) می‌رسد و مطمئناً چیزی را در داخل نمی‌شکند. برای تقویت آموخته هایتان، پیشنهاد می کنیم یک درس ویدیویی از دوره جاوا ما تماشا کنید
نظرات
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION