CodeGym/Java Blog/Random/Mga nested na panloob na klase
John Squirrels
Antas
San Francisco

Mga nested na panloob na klase

Nai-publish sa grupo
Hi! Ngayon ay tatalakayin natin ang isang mahalagang paksa - kung paano gumagana ang mga nested na klase sa Java. Hinahayaan ka ng Java na lumikha ng mga klase sa loob ng isa pang klase:
class OuterClass {
    ...
    static class StaticNestedClass {
        ...
    }
    class InnerClass {
        ...
    }
}
Ang mga panloob na klase na ito ay tinatawag na nested. Nahahati sila sa 2 uri:
  1. Mga non-static na nested na klase. Ang mga ito ay tinatawag ding mga panloob na klase.
  2. Mga static na nested na klase.
Sa turn, ang mga panloob na klase ay may dalawang natatanging subcategory. Bilang karagdagan sa isang panloob na klase na simpleng pagiging isang panloob na klase, maaari rin itong maging:
  • isang lokal na klase
  • isang hindi kilalang klase
nalilito? :) Ayos lang iyon. Narito ang isang diagram para sa kalinawan. Balikan ito sa panahon ng aralin kung bigla kang nalilito! Mga nested na panloob na klase - 2Sa aralin ngayon, tatalakayin natin ang mga panloob na klase (kilala rin bilang mga non-static na nested na klase). Espesyal na naka-highlight ang mga ito sa pangkalahatang diagram para hindi ka maligaw :) Magsimula tayo sa malinaw na tanong: bakit tinawag silang "panloob" na mga klase? Ang sagot ay medyo simple: dahil sila ay nilikha sa loob ng ibang mga klase. Narito ang isang halimbawa:
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!");
       }
   }
}
Eto na ang klase namin Bicycle. Mayroon itong 2 field at 1 method: start(). Mga nested na panloob na klase - 3Naiiba ito sa isang ordinaryong klase dahil naglalaman ito ng dalawang klase: Handlebarat Seat. Ang kanilang code ay nakasulat sa loob ng Bicycleklase. Ang mga ito ay ganap na mga klase: tulad ng nakikita mo, bawat isa sa kanila ay may sariling mga pamamaraan. Sa puntong ito, maaaring may tanong ka: bakit sa mundo natin ilalagay ang isang klase sa isa pa? Bakit ginagawa silang mga panloob na klase? Well, ipagpalagay na kailangan namin ng hiwalay na mga klase para sa mga konsepto ng handlebar at upuan sa aming programa. Syempre, hindi naman natin kailangan gawin silang nested! Maaari tayong gumawa ng mga ordinaryong klase. Halimbawa, tulad nito:
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!");
   }
}
Napakagandang tanong! Siyempre, hindi tayo nalilimitahan ng teknolohiya. Ang paggawa nito ay tiyak na isang opsyon. Dito, ang mahalagang bagay ay mas tamang disenyo ng mga klase mula sa pananaw ng isang partikular na programa at layunin nito. Ang mga panloob na klase ay para sa paghihiwalay ng isang entity na hindi mapaghihiwalay na konektado sa isa pang entity. Ang mga handlebar, upuan, at pedal ay mga bahagi ng isang bisikleta. Hiwalay sa bisikleta, wala silang katuturan. Kung ginawa naming hiwalay ang lahat ng mga konseptong ito sa mga pampublikong klase, magkakaroon kami ng ganitong code sa aming programa:
public class Main {

   public static void main(String[] args) {
       Handlebar handlebar = new Handlebar();
       handlebar.right();
   }
}
Hmm... Mahirap pa ngang ipaliwanag ang kahulugan ng code na ito. Mayroon kaming ilang hindi malinaw na manibela (Bakit kailangan? Walang ideya, sa totoo lang). At ang hawakan na ito ay lumiliko sa kanan... mag-isa, walang bisikleta... sa ilang kadahilanan. Sa pamamagitan ng paghihiwalay ng konsepto ng manibela mula sa konsepto ng bisikleta, nawalan kami ng ilang lohika sa aming programa. Gamit ang isang panloob na klase, ang code ay mukhang ibang-iba:
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 ng console:
Seat up!
Let's go!
Steer left!
Steer right!
Ngayon ang nakikita natin ay biglang may katuturan! :) Gumawa kami ng bagay sa bisikleta. Gumawa kami ng dalawang "subobject" ng bisikleta — isang manibela at isang upuan. Itinaas namin ang upuan para komportable at umalis na kami: pagpedal at pagpipiloto kung kinakailangan! :) Ang mga pamamaraan na kailangan namin ay tinatawag sa naaangkop na mga bagay. Ang lahat ng ito ay simple at maginhawa. Sa halimbawang ito, ang paghihiwalay sa handlebar at upuan ay nagpapahusay ng encapsulation (tinatago namin ang data tungkol sa mga bahagi ng bisikleta sa loob ng nauugnay na klase) at hinahayaan kaming gumawa ng mas detalyadong abstraction. Ngayon tingnan natin ang ibang sitwasyon. Ipagpalagay na gusto naming lumikha ng isang programa na gayahin ang isang tindahan ng bisikleta at mga ekstrang bahagi para sa mga bisikleta. Mga nested na panloob na klase - 4Sa sitwasyong ito, hindi gagana ang dati nating solusyon. Sa isang tindahan ng bisikleta, ang bawat indibidwal na bahagi ng bisikleta ay may katuturan kahit na nakahiwalay sa isang bisikleta. Halimbawa, kakailanganin namin ng mga pamamaraan tulad ng "magbenta ng mga pedal sa isang customer", "bumili ng bagong upuan", atbp. Magiging isang pagkakamali na gumamit ng mga panloob na klase dito — bawat indibidwal na bahagi ng bisikleta sa aming bagong programa ay may kahulugan na nakatayo sa sarili nito: maaari itong ihiwalay sa konsepto ng isang bisikleta. Ito mismo ang kailangan mong bigyang pansin kung iniisip mo kung dapat mong gamitin ang mga panloob na klase o ayusin ang lahat ng entity bilang magkakahiwalay na klase. Mahusay ang Object-oriented na programming dahil ginagawa nitong madali ang pag-modelo ng mga real-world na entity. Maaaring ito ang iyong gabay na prinsipyo kapag nagpapasya kung gagamit ng mga panloob na klase. Sa totoong tindahan, Ang mga ekstrang bahagi ay hiwalay sa mga bisikleta — ayos lang ito. Nangangahulugan ito na okay din kapag nagdidisenyo ng isang programa. Okay, nalaman na natin ang "pilosopiya" :) Ngayon ay kilalanin natin ang mahahalagang "teknikal" na mga tampok ng mga panloob na klase. Narito ang tiyak na kailangan mong tandaan at maunawaan:
  1. Ang isang bagay ng isang panloob na klase ay hindi maaaring umiral nang walang isang bagay ng isang panlabas na klase.

    Makatuwiran ito: ito ang dahilan kung bakit ginawa namin ang Seatat Handlebarpanloob na mga klase sa aming programa — upang hindi kami mauwi sa mga ulilang manibela at upuan.

    Ang code na ito ay hindi nag-compile:

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

    Ang isa pang mahalagang tampok ay sumusunod mula dito:

  2. Ang isang bagay ng isang panloob na klase ay may access sa mga variable ng panlabas na klase.

    Halimbawa, magdagdag tayo ng int seatPostDiametervariable (kumakatawan sa diameter ng seatpost) sa ating Bicycleklase.

    Pagkatapos sa Seatpanloob na klase, maaari tayong lumikha ng isang displaySeatProperties()paraan na nagpapakita ng mga katangian ng upuan:

    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);
           }
       }
    }

    At ngayon ay maipapakita namin ang impormasyong ito sa aming programa:

    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 ng console:

    Seat properties: seatpost diameter = 40

    Tandaan:ang bagong variable ay idineklara na may pinakamahigpit na access modifier ( private). At mayroon pa ring access ang panloob na klase!

  3. Ang isang bagay ng isang panloob na klase ay hindi maaaring gawin sa isang static na pamamaraan ng isang panlabas na klase.

    Ito ay ipinaliwanag sa pamamagitan ng mga partikular na tampok kung paano nakaayos ang mga panloob na klase. Ang isang panloob na klase ay maaaring magkaroon ng mga konstruktor na may mga parameter, o ang default na konstruktor lamang. Ngunit anuman, kapag lumikha tayo ng isang bagay ng isang panloob na klase, ang isang sanggunian sa bagay ng panlabas na klase ay hindi nakikitang ipinapasa sa nilikha na bagay ng panloob na klase. Pagkatapos ng lahat, ang pagkakaroon ng naturang object reference ay isang ganap na kinakailangan. Kung hindi, hindi kami makakagawa ng mga bagay ng inner class.

    Ngunit kung ang isang paraan ng panlabas na klase ay static, kung gayon maaari tayong walang object ng panlabas na klase! At ito ay magiging isang paglabag sa lohika kung paano gumagana ang isang panloob na klase. Sa sitwasyong ito, bubuo ng error ang compiler:

    public static Seat createSeat() {
    
       // Bicycle.this cannot be referenced from a static context
       return new Seat();
    }
  4. Ang isang panloob na klase ay hindi maaaring maglaman ng mga static na variable at pamamaraan.

    Ang lohika ay pareho: ang mga static na pamamaraan at mga variable ay maaaring umiral at matatawag o i-reference kahit na wala ang isang bagay.

    Ngunit kung walang object ng outer class, hindi tayo magkakaroon ng access sa inner class.

    Isang malinaw na kontradiksyon! Ito ang dahilan kung bakit hindi pinapayagan ang mga static na variable at pamamaraan sa mga panloob na klase.

    Ang compiler ay bubuo ng error kung susubukan mong likhain ang mga ito:

    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. Kapag lumilikha ng isang bagay ng isang panloob na klase, ang access modifier nito ay mahalaga.

    Maaaring markahan ang isang panloob na klase ng mga karaniwang modifier ng access: public, private, protected, at package private.

    Bakit ito mahalaga?

    Nakakaapekto ito kung saan tayo makakagawa ng mga instance ng inner class sa ating programa.

    Kung ang aming Seatklase ay idineklara bilang public, maaari kaming lumikha Seatng mga bagay sa anumang iba pang klase. Ang tanging kinakailangan ay ang isang bagay ng panlabas na uri ay dapat ding umiral.

    By the way, nagawa na namin ito dito:

    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();
       }
    }

    Madali kaming nakakuha ng access sa Handlebarinner class mula sa Mainklase.

    Kung idedeklara natin ang inner class bilang private, makakagawa lang tayo ng mga object sa loob ng outer class.

    Hindi na kami makakagawa ng Seatobject "sa labas":

    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();
       }
    }

    Malamang naiintindihan mo na ang logic :)

  6. Ang mga modifier ng access para sa mga panloob na klase ay gumagana katulad ng para sa mga ordinaryong variable.

    Ang protectedmodifier ay nagbibigay ng access sa isang instance variable sa mga subclass at class na nasa parehong package.

    protectedgumagana din para sa mga panloob na klase. Maaari tayong lumikha protectedng mga bagay ng panloob na klase:

    • sa panlabas na uri;
    • sa mga subclass nito;
    • sa mga klase na nasa parehong pakete.

    Kung ang inner class ay walang access modifier ( package private), ang mga object ng inner class ay maaaring malikha:

    • sa panlabas na uri;
    • sa mga klase na nasa parehong pakete.

    Matagal ka nang pamilyar sa mga modifier, kaya walang problema dito.

Sa ngayon lang yan :) Pero wag kang magpapabaya! Ang mga panloob na klase ay isang medyo malawak na paksa na patuloy nating tuklasin sa susunod na aralin. Ngayon ay maaari mong i-refresh ang iyong memorya ng aralin ng aming kurso sa mga panloob na klase . At sa susunod, pag-usapan natin ang tungkol sa mga static na nested na klase.
Mga komento
  • Sikat
  • Bago
  • Luma
Dapat kang naka-sign in upang mag-iwan ng komento
Wala pang komento ang page na ito