JavaRush /Java Blog /Random-ID /Pengambil dan penyetel

Pengambil dan penyetel

Dipublikasikan di grup Random-ID
Halo! Dalam kuliah sebelumnya, Anda telah mempelajari cara membuat kelas lengkap Anda sendiri, dengan bidang dan metode. Ini adalah kemajuan yang serius, bagus sekali! Tapi sekarang aku harus memberitahumu sebuah kebenaran yang tidak menyenangkan. Kami tidak membuat kelas kami dengan benar! Mengapa? Sekilas, tidak ada kesalahan di kelas ini:
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!");
   }
}
Faktanya, ada. Bayangkan saat duduk di tempat kerja Anda menulis kelas seperti ini Cat, yang melambangkan kucing. Dan dia pulang. Saat Anda pergi, programmer lain datang untuk bekerja, membuat kelasnya sendiri Main, di mana dia mulai menggunakan kelas yang Anda tulis Cat.
public class Main {

   public static void main(String[] args) {

       Cat cat = new Cat();
       cat.name = "";
       cat.age = -1000;
       cat.weight = 0;
   }
}
Tidak peduli mengapa dia melakukannya atau bagaimana hal itu terjadi: mungkin orang tersebut lelah atau kurang tidur. Hal lain yang penting: kelas kami saat ini Catmemungkinkan Anda untuk menetapkan nilai-nilai gila ke bidang. Akibatnya, program tersebut berisi objek dengan keadaan yang salah, seperti kucing berusia -1000 tahun ini. Kesalahan apa yang akhirnya kita buat? Saat kami membuat kelas, kami mengekspos datanya. Bidang name, agedan weightberada dalam domain publik. Mereka dapat diakses di mana saja dalam program: cukup buat objek Cat- dan hanya itu, programmer mana pun memiliki akses ke datanya secara langsung melalui operator “ .
Cat cat = new Cat();
cat.name = "";
Di sini kita langsung mengakses bidang tersebut namedan menetapkan nilainya. Kita perlu melindungi data kita dari gangguan luar yang tidak benar. Apa yang dibutuhkan untuk ini? Pertama, semua variabel instan (bidang) harus ditandai dengan pengubah private. Pribadi adalah pengubah akses paling ketat di Java. Jika Anda menggunakannya, bidang kelas Cattidak akan dapat diakses di luarnya.
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!
   }
}
Kompiler melihat ini dan segera menghasilkan kesalahan. Sekarang ladang tersebut tampaknya terlindungi. Namun ternyata akses ke sana “sangat” tertutup: program tersebut bahkan tidak bisa mendapatkan bobot kucing yang ada, jika diperlukan. Ini juga bukan suatu pilihan: dalam bentuk ini kelas kita secara praktis tidak mungkin digunakan. Idealnya kita perlu memberikan semacam akses terbatas pada data:
  • Pemrogram lain harus bisa membuat objekCat
  • Mereka harus bisa membaca data dari objek yang sudah ada (misalnya, mendapatkan nama atau umur kucing yang sudah ada)
  • Nilai bidang juga harus dapat ditetapkan. Tapi pada saat yang sama - hanya nilai yang benar. Benda kita harus dilindungi dari yang salah (tidak ada “umur = -1000 tahun” dan sejenisnya).
Daftar persyaratannya lumayan! Namun pada kenyataannya, semua ini mudah dicapai dengan menggunakan metode khusus - getter dan setter .
Pengambil dan penyetel - 2
Namanya berasal dari bahasa Inggris “ dapatkan ” - “ terima ” (yaitu, “metode untuk mendapatkan nilai suatu bidang”) dan set - “ set ” (yaitu, “metode untuk menetapkan nilai suatu bidang”). Mari kita lihat tampilannya dengan menggunakan kelas kita sebagai contoh 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;
   }
}
Seperti yang Anda lihat, semuanya cukup sederhana :) Nama mereka paling sering terdiri dari kata get/set + nama bidang yang menjadi tanggung jawab mereka. Misalnya, suatu metode getWeight()mengembalikan nilai bidang weightobjek yang dipanggil. Ini adalah tampilan programnya:
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);
   }
}
Keluaran konsol:

Name кота: Барсик
Возраст кота: 5
Вес кота: 4
Sekarang dari kelas lain ( Main) ada akses ke field Cat, namun hanya melalui getter . Harap dicatat bahwa pengambil memiliki pengubah akses public, artinya mereka dapat diakses dari mana saja dalam program. Bagaimana dengan menetapkan nilai? Metode penyetel bertanggung jawab untuk ini
public void setName(String name) {
   this.name = name;
}
Pekerjaan mereka, seperti yang Anda lihat, juga sederhana. Kita memanggil metode setName()pada suatu objek Cat, meneruskannya dengan string sebagai argumen, dan string ini ditugaskan ke bidang nameobjek kita.
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());
   }
}
Di sini kami menggunakan getter dan setter. Pertama, dengan menggunakan pengambil, kami menerima dan menampilkan nama awal kucing ke konsol. Kemudian, dengan menggunakan penyetel, namenilai baru ditetapkan ke bidangnya - “Vasily”. Dan kemudian, dengan menggunakan pengambil, kami mendapatkan nama itu lagi untuk memeriksa apakah itu benar-benar berubah. Keluaran konsol:

Изначальное Name кота — Барсик
Новое Name кота — Васorй
Tampaknya, apa bedanya? Kami juga dapat menetapkan nilai yang salah ke bidang objek, meskipun kami memiliki penyetel:
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");
   }
}
Keluaran konsol:

Возраст Барсика — -1000 лет
Perbedaannya adalah bahwa setter adalah metode yang lengkap . Dan dalam suatu metode, tidak seperti bidang, Anda dapat memasukkan logika verifikasi yang Anda perlukan untuk mencegah nilai yang tidak dapat diterima. Misalnya, Anda dapat dengan mudah menonaktifkan penetapan angka negatif berdasarkan usia:
public void setAge(int age) {
   if (age >= 0) {
       this.age = age;
   } else {
       System.out.println("Error! Age cannot be negative!");
   }
}
Dan sekarang kode kita berfungsi dengan benar!
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");
   }
}
Keluaran konsol:

Ошибка! Возраст не может быть отрицательным числом!
Возраст Барсика — 5 лет
Ada batasan di dalam penyetel, dan ini melindungi dari upaya menyetel data yang salah. Usia Barsik tetap tidak berubah. Pengambil dan penyetel harus selalu dibuat. Meskipun bidang Anda tidak memiliki batasan pada nilai yang mungkin, tidak akan ada kerugian dari bidang tersebut. Bayangkan sebuah situasi: Anda dan kolega Anda sedang menulis sebuah program bersama. Anda membuat kelas Catdengan bidang publik, dan semua pemrogram menggunakannya sesuai keinginan. Dan kemudian suatu hari Anda sadar: “Sial, cepat atau lambat seseorang mungkin secara tidak sengaja memberikan angka negatif ke suatu variabel weight! Kita perlu membuat setter dan menjadikan semua bidang bersifat pribadi!” Anda membuatnya, dan semua kode yang ditulis oleh kolega Anda langsung rusak. Lagi pula, mereka telah menulis banyak kode di mana mereka mengakses kolom Catsecara langsung.
cat.name = "Hippopotamus";
Dan sekarang bidang tersebut telah menjadi pribadi dan kompiler menghasilkan banyak kesalahan!
cat.name = "Hippopotamus";//error! The name field of the Cat class has private access!
Dalam situasi seperti ini, akan lebih baik untuk menyembunyikan bidang dan membuat pengambil-penyetel dari awal . Semua kolega Anda akan menggunakannya, dan jika Anda terlambat menyadari bahwa Anda perlu membatasi nilai bidang, Anda cukup menambahkan tanda centang di dalam penyetel. Dan tidak ada yang akan melanggar kode yang sudah tertulis. Tentu saja, jika Anda ingin akses baca-saja ke bidang tertentu, Anda dapat membuat satu pengambil untuk bidang tersebut. “Di luar”, yaitu, di luar kelas Anda, hanya metode yang tersedia. Datanya harus disembunyikan.
Pengambil dan penyetel - 4
Sebuah analogi dapat dibuat dengan telepon seluler. Bayangkan alih-alih menyalakan ponsel biasa, Anda diberi ponsel dengan casing terbuka, tempat semua kabel, sirkuit, dll. mencuat. Telepon berfungsi: jika Anda berusaha keras dan mengutak-atik diagram, Anda bahkan mungkin dapat menelepon. Tapi Anda mungkin akan merusaknya. Sebaliknya, perusahaan manufaktur memberi Anda antarmuka: klien cukup menghubungi nomor yang diperlukan, menekan tombol hijau pada handset, dan panggilan dimulai. Dan dia tidak peduli apa yang terjadi di dalam sirkuit dan kabel serta bagaimana mereka melakukan tugasnya. Dalam contoh ini, perusahaan memiliki akses terbatas ke “internal” (data) ponsel dan hanya menyisakan antarmuka (metode) di luar. Hasilnya, klien akan mendapatkan apa yang diinginkannya (menelepon) dan pastinya tidak akan merusak apa pun di dalamnya.
Komentar
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION