CodeGym /จาวาบล็อก /สุ่ม /คลาสภายในของ Java
John Squirrels
ระดับ
San Francisco

คลาสภายในของ Java

เผยแพร่ในกลุ่ม
ใน Java บางคลาสสามารถมีคลาสอื่นอยู่ภายในได้ คลาสดังกล่าวเรียกว่าคลาสที่ซ้อนกัน คลาสที่กำหนดภายในคลาสอื่นโดยทั่วไปจะแบ่งออกเป็นสองประเภท — แบบคงที่และไม่คงที่ คลาสที่ไม่คงที่แบบซ้อนกันเรียกว่าภายใน คลาสที่ซ้อนกันที่ถูกประกาศแบบคงที่เรียกว่าคลาสที่ซ้อนกันแบบคงที่ ในความเป็นจริงไม่มีอะไรซับซ้อนที่นี่แม้ว่าคำศัพท์จะดูค่อนข้างคลุมเครือและบางครั้งอาจทำให้นักพัฒนาซอฟต์แวร์มืออาชีพสับสนได้

คลาสที่ซ้อนกันและคลาสภายใน

ดังนั้นคลาสทั้งหมดที่อยู่ในคลาสอื่นจึงเรียกว่าคลาสที่ซ้อนกัน
class OuterClass {
    ...
    class NestedClass {
        ...
    }
}
Nested Classes ที่ไม่คงที่เรียกว่าInner Classesและคลาสคงที่เรียกว่าNested Classes แบบคง ที่ คลาสภายในของ Java - 1
class OuterClass {
    ...
    static class StaticNestedClass {
        ...
    }
    class InnerClass {
        ...
    }
}
ดังนั้น คลาสภายในทั้งหมดจึงซ้อนกัน แต่ไม่ใช่คลาสที่ซ้อนกันทั้งหมดจะเป็นคลาสภายใน นี่คือคำจำกัดความหลัก คลาสภายในเป็นกลไกการรักษาความปลอดภัยชนิดหนึ่งใน Java เรารู้ว่าคลาสธรรมดาไม่สามารถเชื่อมโยงกับตัวดัดแปลงการเข้าถึงส่วนตัวได้ อย่างไรก็ตาม หากคลาสของเราเป็นสมาชิกของคลาสอื่น คลาสภายในก็สามารถทำให้เป็นคลาสส่วนตัวได้ คุณลักษณะนี้ยังใช้เพื่อเข้าถึงสมาชิกชั้นเรียนส่วนตัวด้วย

ตัวอย่างชั้นภายใน

ดังนั้น เรามาลองสร้างคลาสขึ้นมาและภายในคลาสนั้นก็เป็นอีกคลาสหนึ่งกัน ลองนึกภาพคอนโซลเกมแบบโมดูลาร์บางประเภท มี "กล่อง" ในตัวและสามารถเชื่อมต่อโมดูลบางตัวเข้ากับมันได้ ตัวอย่างเช่นตัวควบคุมเกม, พวงมาลัย, หมวก VR ซึ่งตามกฎแล้วจะไม่ทำงานหากไม่มีคอนโซล ที่นี่เรามีคลาส GameConsole มี 2 ​​ฟิลด์และ 1 วิธี — start( ) ความแตกต่างระหว่างGameCosoleและคลาสที่เราคุ้นเคยก็คือมันมีคลาส GameController ภายใน
public class GameConsole {
    private String model;
    private int weight;

    public void run() {
        System.out.println("Game console is on");
    }


    public class GameController {

        private String color;

        public void start() {
            System.out.println("start button is pressed");
        }

        public void x() {
            System.out.println("x button is pressed");
        }

        public void y() {
            System.out.println("y button is pressed");
        }
        public void a() {
            System.out.println("a button is pressed");
        }

        public void b() {
            System.out.println("b button is pressed");
        }
        public void mover() {
            System.out.println("mover button is pressed");
        }

    }

}
ณ จุดนี้ คุณอาจสงสัยว่า: ทำไมไม่ทำให้คลาสเหล่านี้ "แยกจากกัน"? ไม่จำเป็นต้องทำให้มันซ้อนกัน แท้จริงแล้วมันเป็นไปได้ แต่เป็นเรื่องเกี่ยวกับการออกแบบคลาสที่ถูกต้องในแง่ของการใช้งาน คลาสภายในถูกสร้างขึ้นเพื่อเน้นในโปรแกรมถึงเอนทิตีที่เชื่อมโยงกับเอนทิตีอื่นอย่างแยกไม่ออก ตัวควบคุมหรือหมวกกันน็อค VR เป็นต้น เป็นส่วนประกอบของคอนโซล ใช่ สามารถซื้อแยกต่างหากจากคอนโซลได้ แต่จะไม่สามารถใช้งานได้หากไม่มีคอนโซล ถ้าเราแยกคลาสเหล่านี้ออกจากคลาสสาธารณะ โปรแกรมของเราอาจมีโค้ดต่อไปนี้:
public class Main {

   public static void main(String[] args) {
       GameController controller = new GameController();
       controller.x();
   }
}
สิ่งที่เกิดขึ้นในกรณีนี้ยังไม่ชัดเจน เนื่องจากตัวควบคุมจะไม่ทำงานหากไม่มีคอนโซล เราได้สร้างวัตถุคอนโซลเกม เราได้สร้างวัตถุย่อยขึ้นมา — ตัวควบคุมเกม และตอนนี้เราก็เล่นได้แล้วเพียงกดปุ่มที่ถูกต้อง วิธีการที่เราต้องการถูกเรียกบนวัตถุที่ถูกต้อง ทุกอย่างเรียบง่ายและสะดวกสบาย ในตัวอย่างนี้ การแยกตัวควบคุมเกมจะช่วยเพิ่มการห่อหุ้ม (เราซ่อนรายละเอียดของส่วนคอนโซลภายในคลาสที่เกี่ยวข้อง) และช่วยให้สามารถสรุปรายละเอียดได้มากขึ้น แต่หากเราสร้างโปรแกรมจำลองร้านค้าที่คุณสามารถซื้อหมวกกันน็อคหรือคอนโทรลเลอร์ VR แยกต่างหาก ตัวอย่างนี้จะล้มเหลว จะดีกว่าถ้าสร้างตัวควบคุมเกมแยกกัน ลองมาอีกตัวอย่างหนึ่ง เราได้กล่าวไว้ข้างต้นว่าเราสามารถทำให้คลาสภายในเป็นส่วนตัวและยังคงเรียกมันจากคลาสภายนอกได้ ด้านล่างนี้เป็นตัวอย่างของคลาสดังกล่าว
class OuterClass {

   // inner class
   private class InnerClass {
       public void print() {
           System.out.println("We are in the inner class...");
       }
   }

   // method of outer class. We are create an inner class from the method of outer one
   void display() {
       InnerClass inner = new InnerClass();
       inner.print();
   }
}
ในที่นี้OuterClassคือคลาสภายนอกInnerClassคือคลาสภายในdisplay()เป็นวิธีการภายในที่เรากำลังสร้างอ็อบเจ็กต์ของคลาสภายใน ตอนนี้เรามาเขียนคลาสสาธิตด้วยวิธีการหลักที่เราจะเรียกใช้เมธอดdisplay ()
public class OuterDemoMain {

       public static void main(String args[]) {
           // create an object of the outer class
           OuterDemo outer = new OuterDemo();

           outer.display();
       }
}
หากคุณรันโปรแกรมนี้ คุณจะได้รับผลลัพธ์ดังต่อไปนี้:
เราอยู่ในชั้นเรียนชั้นใน...

การจำแนกชั้นเรียนภายใน

คลาสภายในนั้นเองหรือคลาสที่ไม่คงที่ที่ซ้อนกันแบ่งออกเป็นสามกลุ่ม
  • ชั้นในเหมือนเดิม มีเพียงคลาสที่ไม่คงที่เพียงคลาสเดียวภายในอีกคลาสหนึ่งดังที่เราสาธิตข้างต้นด้วยตัวอย่างGameConsoleและGameController
  • คลาสภายในเมธอดท้องถิ่นเป็นคลาสภายในเมธอด
  • คลาสภายในที่ไม่เปิดเผยตัวตน
คลาสภายใน Java - 2

วิธีการเรียนภายในท้องถิ่น

ใน Java คุณสามารถเขียนคลาสภายในเมธอดและเป็นประเภทในเครื่องได้ เช่นเดียวกับตัวแปรท้องถิ่น ขอบเขตของคลาสภายในถูกจำกัดภายในวิธีการ คลาสภายในของเมธอดท้องถิ่นสามารถสร้างขึ้นได้ภายในวิธีการที่กำหนดคลาสภายในเท่านั้น เรามาสาธิตวิธีการใช้เมธอดภายในคลาสกัน
public class OuterDemo2 {

   //instance method of the outer class OuterDemo2
   void myMethod() {
       String str = "and it's a value from OuterDemo2 class' myMethod ";

       // method-local inner class
       class methodInnerDemo {
           public void print() {
               System.out.println("Here we've got a method inner class... " );
               System.out.println(str);

           }
       }

       // Access to the inner class
       methodInnerDemo inn = new methodInnerDemo();
       inn.print();
   }
}
ตอนนี้เรากำลังจะเขียนคลาสสาธิตด้วย วิธี การหลักที่เราจะเรียกใช้เมธอดexternal()
public class OuterDemoMain {


   public static void main(String args[]) {
       OuterDemo2 outer = new OuterDemo2();
       outer.myMethod();
   }
}
ผลลัพธ์คือ:
ที่นี่เรามีเมธอดคลาสภายใน... และมันคือค่าจากคลาส OuterDemo2 'myMethod

ชนชั้นภายในที่ไม่เปิดเผยตัวตน

คลาสภายในที่ประกาศโดยไม่มีชื่อคลาสเรียกว่าคลาสภายในที่ไม่ระบุชื่อ เมื่อเราประกาศชนชั้นภายในที่ไม่เปิดเผยตัวตน เราจะยกตัวอย่างทันที โดยทั่วไปแล้ว คลาสดังกล่าวจะใช้เมื่อใดก็ตามที่คุณต้องการแทนที่คลาสหรือวิธีอินเทอร์เฟซ
abstract class OuterDemo3 {
   public abstract void method();

}
   class outerClass {

       public static void main(String args[]) {
           OuterDemo3 inner = new OuterDemo3() {
               public void method() {
                   System.out.println("Here we've got an example of an  anonymous inner class");
               }
           };
           inner.method();
       }
   }
ผลลัพธ์อยู่ที่นี่:
เรามีตัวอย่างของชนชั้นภายในที่ไม่เปิดเผยตัวตน...

คลาสภายในที่ไม่เปิดเผยตัวตนเป็นข้อโต้แย้ง

คุณยังสามารถส่งคลาสภายในที่ไม่ระบุชื่อเป็นอาร์กิวเมนต์ไปยังเมธอดได้ นี่คือตัวอย่าง
interface OuterDemo4 {
       String hello();
   }

   class NewClass {
       // accepts the object of interface
       public void displayMessage(OuterDemo4 myMessage) {
           System.out.println(myMessage.hello());
           System.out.println("example of anonymous inner class as an argument");
       }

       public static void main(String args[]) {
           NewClass newClass = new NewClass();

           //here we pass an anonymous inner class as an argument
           newClass.displayMessage(new OuterDemo4() {
               public String hello() {
                   return "Hello!";
               }
           });
       }
}
ผลลัพธ์อยู่ที่นี่:
สวัสดี! ตัวอย่างของชนชั้นภายในที่ไม่เปิดเผยตัวตนเป็นข้อโต้แย้ง
เพื่อเสริมสิ่งที่คุณเรียนรู้ เราขอแนะนำให้คุณชมบทเรียนวิดีโอจากหลักสูตร Java ของเรา
ความคิดเห็น
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION