CodeGym/Blog Java/rawak/Kelas dalaman bersarang
John Squirrels
Tahap
San Francisco

Kelas dalaman bersarang

Diterbitkan dalam kumpulan
Hai! Hari ini kita akan membincangkan topik penting - cara kelas bersarang berfungsi di Java. Java membolehkan anda membuat kelas di dalam kelas lain:
class OuterClass {
    ...
    static class StaticNestedClass {
        ...
    }
    class InnerClass {
        ...
    }
}
Kelas dalaman ini dipanggil bersarang. Mereka dibahagikan kepada 2 jenis:
  1. Kelas bersarang bukan statik. Ini juga dipanggil kelas dalaman.
  2. Kelas bersarang statik.
Sebaliknya, kelas dalaman mempunyai dua subkategori yang berbeza. Sebagai tambahan kepada kelas dalaman semata-mata menjadi kelas dalaman, ia juga boleh menjadi:
  • kelas tempatan
  • kelas tanpa nama
keliru? :) Tak mengapa. Berikut ialah gambar rajah untuk kejelasan. Kembali kepadanya semasa pelajaran jika anda tiba-tiba mendapati diri anda keliru! Kelas dalaman bersarang - 2Dalam pelajaran hari ini, kita akan membincangkan kelas dalam (juga dikenali sebagai kelas bersarang bukan statik). Mereka diserlahkan khas dalam rajah keseluruhan supaya anda tidak tersesat :) Mari kita mulakan dengan soalan yang jelas: mengapa mereka dipanggil kelas "dalaman"? Jawapannya agak mudah: kerana ia dicipta di dalam kelas lain. Berikut adalah contoh:
public class Bicycle {

   private String model;
   private int weight;

   public Bicycle(String model, int weight) {
       this.model = model;
       this.weight = weight;
   }

   public void start() {
       System.out.println("Let's go!");
   }

   public class Handlebar {

       public void right() {
           System.out.println("Steer right!");
       }

       public void left() {

           System.out.println("Steer left!");
       }
   }

   public class Seat {

       public void up() {

           System.out.println("Seat up!");
       }

       public void down() {

           System.out.println("Seat down!");
       }
   }
}
Di sini kita mempunyai Bicyclekelas. Ia mempunyai 2 medan dan 1 kaedah: start(). Kelas dalaman bersarang - 3Ia berbeza daripada kelas biasa kerana ia mengandungi dua kelas: Handlebardan Seat. Kod mereka ditulis di dalam Bicyclekelas. Ini adalah kelas lengkap: seperti yang anda lihat, setiap daripada mereka mempunyai kaedah sendiri. Pada ketika ini, anda mungkin mempunyai soalan: mengapa di dunia ini kita akan meletakkan satu kelas di dalam kelas lain? Mengapa menjadikan mereka kelas dalaman? Baiklah, katakan kita memerlukan kelas berasingan untuk konsep hendal dan tempat duduk dalam program kita. Sudah tentu, kita tidak perlu membuat mereka bersarang! Kita boleh buat kelas biasa. Sebagai contoh, seperti ini:
public class Handlebar {
   public void right() {
       System.out.println("Steer right!");
   }

   public void left() {

       System.out.println("Steer left");
   }
}

public class Seat {

   public void up() {

       System.out.println("Seat up!");
   }

   public void down() {

       System.out.println("Seat down!");
   }
}
Soalan yang sangat bagus! Sudah tentu, kita tidak terhad oleh teknologi. Melakukannya sudah tentu satu pilihan. Di sini, perkara penting ialah reka bentuk kelas yang betul dari perspektif program tertentu dan tujuannya. Kelas dalaman adalah untuk mengasingkan entiti yang berkait rapat dengan entiti lain. Bar hendal, tempat duduk dan pedal adalah komponen basikal. Dipisahkan dari basikal, mereka tidak masuk akal. Jika kami membuat semua konsep ini memisahkan kelas awam, kami akan mempunyai kod seperti ini dalam program kami:
public class Main {

   public static void main(String[] args) {
       Handlebar handlebar = new Handlebar();
       handlebar.right();
   }
}
Hmm... Maksud kod ni pun susah nak terangkan. Kami mempunyai beberapa hendal yang samar-samar (Mengapa perlu? Tidak ada idea, sejujurnya). Dan pemegang ini membelok ke kanan... dengan sendirinya, tanpa basikal... atas sebab tertentu. Dengan mengasingkan konsep hendal daripada konsep basikal, kami kehilangan sedikit logik dalam program kami. Menggunakan kelas dalaman, kod itu kelihatan sangat berbeza:
public class Main {

   public static void main(String[] args) {

       Bicycle peugeot = new Bicycle("Peugeot", 120);
       Bicycle.Handlebar handlebar = peugeot.new Handlebar();
       Bicycle.Seat seat = peugeot.new Seat();

       seat.up();
       peugeot.start();
       handlebar.left();
       handlebar.right();
   }
}
Output konsol:
Seat up!
Let's go!
Steer left!
Steer right!
Sekarang apa yang kita lihat tiba-tiba masuk akal! :) Kami mencipta objek basikal. Kami mencipta dua "subobjek" basikal — bar hendal dan tempat duduk. Kami menaikkan tempat duduk untuk keselesaan dan kami pergi: mengayuh dan mengemudi mengikut keperluan! :) Kaedah yang kita perlukan dipanggil pada objek yang sesuai. Semuanya mudah dan selesa. Dalam contoh ini, mengasingkan bar hendal dan tempat duduk meningkatkan enkapsulasi (kami menyembunyikan data tentang bahagian basikal di dalam kelas yang berkaitan) dan membolehkan kami membuat abstraksi yang lebih terperinci. Sekarang mari kita lihat situasi yang berbeza. Katakan kita ingin mencipta program yang menyerupai kedai basikal dan alat ganti untuk basikal. Kelas dalaman bersarang - 4Dalam keadaan ini, penyelesaian kami sebelum ini tidak akan berfungsi. Di kedai basikal, setiap bahagian basikal individu masuk akal walaupun dipisahkan daripada basikal. Sebagai contoh, kami memerlukan kaedah seperti "menjual pedal kepada pelanggan", "beli tempat duduk baharu", dsb. Adalah satu kesilapan untuk menggunakan kelas dalaman di sini — setiap bahagian basikal individu dalam program baharu kami mempunyai makna yang tetap sendiri: ia boleh dipisahkan daripada konsep basikal. Inilah yang perlu anda perhatikan jika anda tertanya-tanya sama ada anda perlu menggunakan kelas dalaman atau menyusun semua entiti sebagai kelas berasingan. Pengaturcaraan berorientasikan objek adalah baik kerana ia memudahkan untuk memodelkan entiti dunia sebenar. Ini boleh menjadi prinsip panduan anda apabila memutuskan sama ada untuk menggunakan kelas dalaman. Di kedai sebenar, alat ganti berasingan daripada basikal — ini tidak mengapa. Ini bermakna ia juga tidak mengapa apabila mereka bentuk program. Okay, kita telah mengetahui "falsafah" :) Sekarang mari kita berkenalan dengan ciri "teknikal" penting kelas dalaman. Inilah perkara yang anda perlu ingat dan fahami:
  1. Objek kelas dalam tidak boleh wujud tanpa objek kelas luar.

    Ini masuk akal: inilah sebabnya kami membuat kelas Seatdan Handlebarkelas dalaman dalam program kami — supaya kami tidak mendapat hendal dan tempat duduk yatim piatu.

    Kod ini tidak menyusun:

    public static void main(String[] args) {
    
       Handlebar handlebar = new Handlebar();
    }

    Satu lagi ciri penting berikut dari ini:

  2. Objek kelas dalam mempunyai akses kepada pembolehubah kelas luar.

    Sebagai contoh, mari tambah int seatPostDiameterpembolehubah (mewakili diameter tiang tempat duduk) pada Bicyclekelas kita.

    Kemudian dalam Seatkelas dalaman, kita boleh mencipta displaySeatProperties()kaedah yang memaparkan sifat tempat duduk:

    public class Bicycle {
    
       private String model;
       private int weight;
    
       private int seatPostDiameter;
    
       public Bicycle(String model, int weight, int seatPostDiameter) {
           this.model = model;
           this.weight = weight;
           this.seatPostDiameter = seatPostDiameter;
    
       }
    
       public void start() {
           System.out.println("Let's go!");
       }
    
       public class Seat {
    
           public void up() {
    
               System.out.println("Seat up!");
           }
    
           public void down() {
    
               System.out.println("Seat down!");
           }
    
           public void displaySeatProperties() {
    
               System.out.println("Seat properties: seatpost diameter = " + Bicycle.this.seatPostDiameter);
           }
       }
    }

    Dan kini kami boleh memaparkan maklumat ini dalam program kami:

    public class Main {
    
       public static void main(String[] args) {
    
           Bicycle bicycle = new Bicycle("Peugeot", 120, 40);
           Bicycle.Seat seat = bicycle.new Seat();
    
           seat.displaySeatProperties();
       }
    }

    Output konsol:

    Seat properties: seatpost diameter = 40

    Catatan:pembolehubah baharu diisytiharkan dengan pengubah suai akses yang paling ketat ( private). Dan kelas dalaman masih mempunyai akses!

  3. Objek kelas dalam tidak boleh dibuat dalam kaedah statik kelas luar.

    Ini dijelaskan oleh ciri khusus tentang cara kelas dalaman dianjurkan. Kelas dalaman boleh mempunyai pembina dengan parameter, atau hanya pembina lalai. Tetapi tidak kira, apabila kita mencipta objek kelas dalam, rujukan kepada objek kelas luar secara halimunan dihantar kepada objek yang dicipta kelas dalam. Lagipun, kehadiran rujukan objek sedemikian adalah keperluan mutlak. Jika tidak, kami tidak akan dapat mencipta objek kelas dalam.

    Tetapi jika kaedah kelas luar adalah statik, maka kita mungkin tidak mempunyai objek kelas luar! Dan ini akan menjadi pelanggaran logik cara kelas dalaman berfungsi. Dalam keadaan ini, pengkompil akan menghasilkan ralat:

    public static Seat createSeat() {
    
       // Bicycle.this cannot be referenced from a static context
       return new Seat();
    }
  4. Kelas dalaman tidak boleh mengandungi pembolehubah dan kaedah statik.

    Logiknya adalah sama: kaedah statik dan pembolehubah boleh wujud dan dipanggil atau dirujuk walaupun tanpa objek.

    Tetapi tanpa objek kelas luar, kita tidak akan mempunyai akses kepada kelas dalam.

    Percanggahan yang jelas! Inilah sebabnya mengapa pembolehubah statik dan kaedah tidak dibenarkan dalam kelas dalaman.

    Pengkompil akan menghasilkan ralat jika anda cuba menciptanya:

    public class Bicycle {
    
       private int weight;
    
    
       public class Seat {
    
           // An inner class cannot have static declarations
           public static void displaySeatProperties() {
    
               System.out.println("Seat properties: seatpost diameter = " + Bicycle.this.seatPostDiameter);
           }
       }
    }
  5. Apabila mencipta objek kelas dalam, pengubah suai aksesnya adalah penting.

    Kelas dalaman boleh ditandakan dengan pengubah suai akses standard: public, private, protected, dan package private.

    Mengapa perkara ini penting?

    Ini mempengaruhi tempat kita boleh mencipta contoh kelas dalaman dalam program kita.

    Jika Seatkelas kami diisytiharkan sebagai public, kami boleh mencipta Seatobjek dalam mana-mana kelas lain. Satu-satunya keperluan ialah objek kelas luar juga mesti wujud.

    By the way, kami sudah melakukan ini di sini:

    public class Main {
    
       public static void main(String[] args) {
    
           Bicycle peugeot = new Bicycle("Peugeot", 120);
           Bicycle.Handlebar handlebar = peugeot.new Handlebar();
           Bicycle.Seat seat = peugeot.new Seat();
    
           seat.up();
           peugeot.start();
           handlebar.left();
           handlebar.right();
       }
    }

    Kami dengan mudah mendapat akses ke Handlebarkelas dalaman daripada Mainkelas.

    Jika kita mengisytiharkan kelas dalam sebagai private, kita akan dapat mencipta objek hanya di dalam kelas luar.

    Kami tidak lagi boleh mencipta Seatobjek "di luar":

    private class Seat {
    
       // Methods
    }
    
    public class Main {
    
       public static void main(String[] args) {
    
           Bicycle bicycle = new Bicycle("Peugeot", 120, 40);
    
           // Bicycle.Seat has private access in Bicycle
           Bicycle.Seat seat = bicycle.new Seat();
       }
    }

    Anda mungkin sudah faham logiknya :)

  6. Pengubah suai akses untuk kelas dalaman berfungsi sama seperti pembolehubah biasa.

    Pengubah protectedsuai menyediakan akses kepada pembolehubah contoh dalam subkelas dan kelas yang berada dalam pakej yang sama.

    protectedjuga berfungsi untuk kelas dalaman. Kita boleh mencipta protectedobjek kelas dalam:

    • dalam kelas luar;
    • dalam subkelasnya;
    • dalam kelas yang berada dalam pakej yang sama.

    Jika kelas dalam tidak mempunyai pengubah akses ( package private), objek kelas dalam boleh dibuat:

    • dalam kelas luar;
    • dalam kelas yang berada dalam pakej yang sama.

    Anda telah biasa dengan pengubah suai untuk masa yang lama, jadi tiada masalah di sini.

Itu sahaja buat masa ini :) Tetapi jangan berlengah! Kelas dalaman ialah topik yang agak luas yang akan kami teruskan dalam pelajaran seterusnya. Kini anda boleh menyegarkan ingatan anda tentang pelajaran kursus kami tentang kelas dalaman . Dan lain kali, mari kita bercakap tentang kelas bersarang statik.
Komen
  • Popular
  • Baru
  • Tua
Anda mesti log masuk untuk meninggalkan ulasan
Halaman ini tidak mempunyai sebarang ulasan lagi