สวัสดี! เรายังคงสำรวจหัวข้อของคลาสที่ซ้อนกันใน Java ในบทเรียนที่แล้ว เราได้พูดคุยเกี่ยวกับคลาสที่ซ้อนกันแบบไม่คงที่ หรือที่เรียกกันว่าคลาสภายใน วันนี้เรามาดูอีกกลุ่มหนึ่งแล้วมาดูคลาสที่ซ้อนกันแบบคงที่ให้ละเอียดยิ่งขึ้น แตกต่างจากกลุ่มอื่นอย่างไร? เมื่อประกาศคลาสดังกล่าว เราจะใช้ static keyword ที่คุ้นเคยอยู่แล้ว:
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
- พิมพ์เขียวเครื่องบิน ในชั้นเรียนนี้ เราสามารถสรุปข้อมูลการบริการทั้งหมดเกี่ยวกับเครื่องบินได้ ในตัวอย่างของเรา เพื่อความง่าย เราจำกัดไว้เพียงปีที่ผลิต แต่อาจมีข้อมูลอื่นๆ ได้มากมาย ดังที่เราได้พูดคุยไปแล้วในการบรรยายครั้งล่าสุด การสร้างคลาสที่ซ้อนกันดังกล่าวจะเพิ่มการห่อหุ้มและส่งเสริมสิ่งที่เป็นนามธรรมที่สมจริงยิ่งขึ้น อะไรคือความแตกต่างระหว่างคลาสที่ซ้อนกันแบบคงที่และแบบไม่คงที่? 1. วัตถุคลาสคงDrawing
ที่ไม่ได้เก็บการอ้างอิงไปยังอินสแตนซ์เฉพาะของคลาสภายนอก จำตัวอย่างจากการบรรยายครั้งล่าสุดเกี่ยวกับจักรยาน:
public class Bicycle {
private String model;
private int mawWeight;
public Bicycle(String model, int mawWeight) {
this.model = model;
this.mawWeight = mawWeight;
}
public void start() {
System.out.println("Go!");
}
public class SteeringWheel {
public void right() {
System.out.println("Steering wheel to the right!");
}
public void left() {
System.out.println("Steering wheel to the left!");
}
}
}
ที่นั่นเราได้พูดคุยเกี่ยวกับวิธีSteeringWheel
การอ้างอิงถึงวัตถุของคลาสภายนอก (จักรยาน) ถูกส่งผ่านไปยังแต่ละอินสแตนซ์ของคลาสภายใน (พวงมาลัย) โดยที่เราไม่รู้Bicycle
ตัว หากไม่มีวัตถุของคลาสภายนอก วัตถุของคลาสภายในก็ไม่สามารถดำรงอยู่ได้ สิ่งนี้ไม่เป็นความจริงสำหรับคลาสที่ซ้อนกันแบบคงที่ อ็อบเจ็กต์ของคลาสที่ซ้อนกันแบบสแตติกสามารถดำรงอยู่ได้อย่างง่ายดายด้วยตัวมันเอง ในเรื่องนี้คลาสแบบคงที่มีความ “อิสระ” มากกว่าคลาสที่ไม่คงที่ จุดเดียวคือเมื่อสร้างวัตถุคุณต้องระบุชื่อของคลาสภายนอก:
public class Main {
public static void main(String[] args) {
Boeing737.Drawing drawing1 = new Boeing737.Drawing();
Boeing737.Drawing drawing2 = new Boeing737.Drawing();
}
}
ทำไมเราถึงทำให้ชั้นเรียนDrawing
คงที่ แต่ในการบรรยายครั้งล่าสุด ชั้นเรียนSeat
(เบาะนั่งจักรยาน) จึงไม่คงที่? เช่นเดียวกับครั้งที่แล้ว มาเพิ่ม "ปรัชญา" เล็กๆ น้อยๆ เพื่อทำความเข้าใจตัวอย่างนี้กัน :) แตกต่างจากเบาะจักรยานตรงที่แก่นแท้ของการวาดภาพไม่ได้ผูกติดอยู่กับแก่นแท้ของเครื่องบินมากนัก วัตถุที่นั่งแยกต่างหากโดยไม่มีจักรยานมักจะไม่มีความหมาย (แม้ว่าจะไม่เสมอไป - เราได้พูดถึงเรื่องนี้ในบทเรียนที่แล้ว) แก่นแท้ของการวาดภาพนั้นสมเหตุสมผลในตัวเอง ตัวอย่างเช่น อาจเป็นประโยชน์สำหรับวิศวกรที่วางแผนการซ่อมเครื่องบิน พวกเขาไม่จำเป็นต้องใช้เครื่องบินในการวางแผน และสามารถวางไว้ที่ใดก็ได้ แค่ภาพวาดก็เพียงพอแล้ว นอกจากนี้ สำหรับเครื่องบินรุ่นเดียวกันทุกลำ ภาพวาดจะยังคงเหมือนเดิม ดังนั้นจึงไม่มีการเชื่อมต่อที่เข้มงวดเท่ากับที่นั่งกับจักรยาน ดังนั้นวัตถุจึง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()
โดยตรงในคลาสที่ซ้อนกัน (ไม่มีเหตุผลเฉพาะสำหรับสิ่งนี้ - เพียงเพื่อให้คุณรู้ว่ามันเป็นไปได้) และสร้างวัตถุ 5 Drawing
ชิ้น แม้ว่าเราจะไม่มีวัตถุของคลาสภายนอกเพียงชิ้นเดียวก็ตาม อย่างที่คุณเห็นไม่มีปัญหา :) เอาต์พุตคอนโซล:
Drawing{id=1}
Drawing{id=2}
Drawing{id=3}
Drawing{id=4}
Drawing{id=5}
นี่เป็นการสรุปบทเรียนของเรา! ในกรณีนี้ ฉันจะทิ้งลิงก์ไปยังส่วนเกี่ยวกับสิ่งเหล่านั้นในเอกสารของ Oracle อ่านหากมีจุดใดที่ไม่ชัดเจน ตอนนี้ได้เวลาแก้ไขปัญหาสองสามข้อแล้ว! :)
GO TO FULL VERSION