สวัสดี! เรายังคงสำรวจหัวข้อของคลาสที่ซ้อนกันใน Java ในแบบฝึกหัดที่แล้ว เราได้พูดถึงคลาสที่ซ้อนกันแบบไม่คงที่ ซึ่งเรียกอีกอย่างว่าคลาส
ภายใน วันนี้เรามาต่อกันที่คลาสกลุ่มอื่น เราจะพิจารณาคลาสที่ซ้อนกันแบบคงที่
แตกต่างจากคลาสอื่นอย่างไร? เมื่อประกาศคลาสประเภทนี้ เราจะใช้คีย์เวิร์ดแบบคงที่ ซึ่งคุณคุ้นเคยอยู่แล้ว:
ในตัวอย่างนี้ เรามี
ดังที่เราได้กล่าวไว้ในบทเรียนที่แล้ว การสร้างคลาสที่ซ้อนกันเช่นนี้จะช่วยปรับปรุงการห่อหุ้มและช่วยให้ได้สิ่งที่เป็นนามธรรมที่สมจริงยิ่งขึ้น ความแตกต่างระหว่างคลาสที่ซ้อนกันแบบคงที่และไม่คงที่คืออะไร 1. วัตถุของ


public class Boeing737 {
private int manufactureYear;
private static int maxPassengersCount = 300;
public Boeing737(int manufactureYear) {
this.manufactureYear = manufactureYear;
}
public int getManufactureYear() {
return manufactureYear;
}
public static class Drawing {
public static int getMaxPassengersCount() {
return maxPassengersCount;
}
}
}

Boeing737
ชั้นนอกซึ่งแสดงถึงเครื่องบินประเภทนี้ มีตัวสร้างที่มีพารามิเตอร์เดียว: ปีที่ผลิต ( int manufactureYear
) นอกจากนี้ยังมีตัวแปรคงที่หนึ่งตัวแปร: จำนวนผู้โดยสารสูงสุด ( int maxPassengersCount
) มันจะมีค่าเท่ากันสำหรับระนาบทั้งหมดในรุ่นเดียวกัน ดังนั้นเราต้องการเพียงหนึ่งอินสแตนซ์ นอกจากนี้ยังมีคลาสที่ซ้อนกันแบบคงที่: Drawing
(แสดงถึงพิมพ์เขียวทางวิศวกรรมของเครื่องบิน) เราใช้คลาสนี้เพื่อสรุปข้อมูลอย่างเป็นทางการทั้งหมดเกี่ยวกับเครื่องบิน ในตัวอย่างของเรา เพื่อความง่าย เราได้จำกัดคลาสนี้ไว้ที่ปีที่ผลิต แต่อาจมีข้อมูลอื่นๆ มากมาย 
Drawing
คลาสสแตติกไม่เก็บการอ้างอิงถึงอินสแตนซ์เฉพาะของคลาสภายนอก จำตัวอย่างจักรยานจากบทเรียนที่แล้ว:
public class Bicycle {
private String model;
private int maxWeight;
public Bicycle(String model, int maxWeight) {
this.model = model;
this.maxWeight = maxWeight;
}
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!");
}
}
}
ในบทเรียนนั้น เราได้พูดคุยเกี่ยวกับข้อเท็จจริงที่ว่าแต่ละตัวอย่างของHandlebar
ชนชั้นใน ซึ่งส่งถึงเราโดยไม่รู้ตัว ผ่านการอ้างอิงถึงตัวอย่างของBicycle
ชนชั้นนอก หากไม่มีอินสแตนซ์ของคลาสภายนอก วัตถุของคลาสภายในก็ไม่สามารถดำรงอยู่ได้ สำหรับคลาสที่ซ้อนกันแบบสแตติก นี่ไม่ใช่กรณี อ็อบเจกต์ของคลาสที่ซ้อนกันแบบสแตติกนั้นสามารถมีอยู่ในตัวมันเองทั้งหมด ในเรื่องนี้ คลาสแบบสแตติกมีความ "อิสระ" มากกว่าแบบไม่คงที่ สิ่งเดียวที่คุณต้องรู้คือเมื่อสร้างวัตถุดังกล่าว คุณต้องระบุชื่อของคลาสภายนอก:
public class Main {
public static void main(String[] args) {
Boeing737.Drawing drawing1 = new Boeing737.Drawing();
Boeing737.Drawing drawing2 = new Boeing737.Drawing();
}
}
ทำไมเราถึงทำให้Drawing
ชั้นเรียนคงที่ในบทเรียนที่แล้วที่เราสร้างSeat
class (แทนที่นั่งจักรยาน) ไม่คงที่? เช่นเดียวกับครั้งที่แล้ว เราจะเพิ่ม "ปรัชญา" เล็กน้อยเพื่อให้เข้าใจตัวอย่าง :) ซึ่งแตกต่างจากที่นั่งจักรยาน แนวคิดของการเขียนแบบทางวิศวกรรมไม่ได้เชื่อมโยงกับแนวคิดของเครื่องบินอย่างเหนียวแน่น หากไม่มีจักรยาน วัตถุที่นั่งจักรยานแยกต่างหากมักจะไม่มีความหมาย (แม้ว่าจะไม่เสมอไป เราได้พูดถึงเรื่องนี้ในบทเรียนที่แล้ว) แนวคิดของการเขียนแบบทางวิศวกรรมมีความหมายในตัวเอง ตัวอย่างเช่น อาจเป็นประโยชน์สำหรับวิศวกรที่วางแผนซ่อมบำรุงเครื่องบิน เครื่องบินไม่จำเป็นในการวางแผนและสามารถอยู่ที่ใดก็ได้ จำเป็นต้องมีการเขียนแบบวิศวกรรมเท่านั้น นอกจากนี้ เครื่องบินทุกลำในรุ่นเดียวกันจะมีภาพวาดของวิศวกรเหมือนกัน ดังนั้นจึงไม่มีความสัมพันธ์ที่แน่นแฟ้นเหมือนที่มีอยู่กับที่นั่งจักรยาน ดังนั้น กDrawing
วัตถุไม่จำเป็นต้องอ้างอิงถึงวัตถุเครื่องบินเฉพาะ 2. การเข้าถึงตัวแปรและวิธีการของคลาสภายนอกที่แตกต่างกัน คลาสที่ซ้อนกันแบบสแตติกสามารถเข้าถึงฟิลด์สแตติกของคลาสภายนอกเท่านั้น ในตัวอย่างของเราDrawing
คลาสมีgetMaxPassengersCount()
เมธอดที่คืนค่าของmaxPassengersCount
ตัวแปรสแตติกของคลาสภายนอก อย่างไรก็ตาม เราไม่สามารถสร้างgetManufactureYear()
เมธอดในDrawing
คลาสเพื่อคืนค่าmanufactureYear
ของ ท้ายที่สุดแล้วmanufactureYear
ตัวแปรจะไม่คงที่ ซึ่งหมายความว่าจะต้องเป็นของอินสแตนซ์เฉพาะBoeing737
ของ และอย่างที่เราค้นพบแล้ว ในกรณีของคลาสซ้อนแบบสแตติก วัตถุของคลาสภายนอกอาจหายไปอย่างง่ายดาย ดังนั้นข้อจำกัด :) ไม่สำคัญว่าตัวดัดแปลงการเข้าถึงใดที่ตัวแปรสแตติกจะมีในคลาสภายนอก แม้ว่ามันจะเป็นprivate
คลาสที่ซ้อนกันแบบคงที่จะยังคงสามารถเข้าถึงได้ จากทั้งหมดข้างต้นไม่เพียงแต่ใช้กับการเข้าถึงตัวแปรสแตติกเท่านั้น แต่ยังรวมถึงเมธอดสแตติกด้วย สำคัญ! ในการประกาศคลาสภายในstatic
คำหลักไม่ได้หมายความว่าคุณสามารถสร้างวัตถุได้เพียงชิ้นเดียว อย่าสับสนวัตถุกับตัวแปร หากเรากำลังพูดถึงตัวแปรสแตติก ใช่แล้ว มีอินสแตนซ์เดียวของตัวแปรคลาสสแตติก ตัวอย่างmaxPassangersCount
เช่น แต่เมื่อstatic
นำไปใช้กับคลาสที่ซ้อนกัน หมายความว่าวัตถุนั้นไม่มีการอ้างอิงถึงวัตถุของคลาสภายนอก และเราสามารถสร้างวัตถุได้มากเท่าที่เราต้องการ:
public class Boeing737 {
private int manufactureYear;
private static int maxPassengersCount = 300;
public Boeing737(int manufactureYear) {
this.manufactureYear = manufactureYear;
}
public int getManufactureYear() {
return manufactureYear;
}
public static class Drawing {
private int id;
public Drawing(int id) {
this.id = id;
}
public static int getPassengersCount() {
return maxPassengersCount;
}
@Override
public String toString() {
return "Drawing{" +
"id=" + id +
'}';
}
public static void main(String[] args) {
for (int i = 1; i < 6; i++) {
Boeing737.Drawing drawing = new Boeing737.Drawing(i);
System.out.println(drawing);
}
}
}
}
เราประกาศmain()
เมธอดโดยตรงในคลาสที่ซ้อนกัน (ไม่มีเหตุผลพิเศษสำหรับเรื่องนี้ — เพียงเพื่อแจ้งให้คุณทราบว่าเป็นไปได้) และสร้างDrawing
ออบเจกต์ 5 รายการ แม้ว่าเราจะไม่มีวัตถุของชั้นนอกแม้แต่ชิ้นเดียว อย่างที่คุณเห็น สิ่งนี้ไม่ได้สร้างปัญหาใดๆ :) เอาต์พุตของคอนโซล:
Drawing{id=1}
Drawing{id=2}
Drawing{id=3}
Drawing{id=4}
Drawing{id=5}
และนั่นก็เป็นการสรุปบทเรียนของเรา! ในกรณีนี้ ฉันจะทิ้งลิงก์ไปยังส่วนเกี่ยวกับพวกเขาไว้ ในเอกสาร ประกอบของ Oracle หากสิ่งที่ยังไม่ชัดเจน โปรดอ่าน ตอนนี้ถึงเวลาที่ฉันต้องแก้ไขงานสองสามอย่างแล้ว! :)
GO TO FULL VERSION