ทำไมเราไม่สามารถมีวิธีสแตติกในคลาสภายในที่ไม่คงที่ได้?
ถ้าฉันทำให้ชั้นในคงที่มันใช้งานได้ ทำไม?
static
")
ทำไมเราไม่สามารถมีวิธีสแตติกในคลาสภายในที่ไม่คงที่ได้?
ถ้าฉันทำให้ชั้นในคงที่มันใช้งานได้ ทำไม?
static
")
คำตอบ:
เนื่องจากอินสแตนซ์ของคลาสภายในมีความสัมพันธ์โดยนัยกับอินสแตนซ์ของคลาสภายนอกของมันจึงไม่สามารถกำหนดวิธีการคงที่ใด ๆ เอง เนื่องจากคลาสที่ซ้อนกันแบบสแตติกไม่สามารถอ้างถึงโดยตรงกับตัวแปรอินสแตนซ์หรือวิธีการที่กำหนดไว้ในคลาสที่ปิดล้อมของมันจึงสามารถใช้พวกเขาผ่านการอ้างอิงวัตถุเท่านั้นจึงปลอดภัยที่จะประกาศวิธีคงที่ในระดับที่ซ้อนกันคงที่
A.B.sync(X)
หรือแม้กระทั่ง (จากภายใน A) B.sync(x)
?
มีจุดไม่มากที่จะอนุญาตให้ใช้วิธีการคงที่ในชั้นในแบบคงที่; คุณจะเข้าถึงมันอย่างไร คุณไม่สามารถเข้าถึง (อย่างน้อยเริ่มต้น) อินสแตนซ์ของคลาสภายในที่ไม่คงที่โดยไม่ต้องผ่านอินสแตนซ์ของคลาสภายนอก ไม่มีวิธีคงที่อย่างหมดจดในการสร้างชั้นในแบบไม่คงที่
สำหรับคลาสภายนอกOuter
คุณสามารถเข้าถึงวิธีแบบคงที่test()
เช่นนี้:
Outer.test();
สำหรับคลาสภายในแบบสแตติกInner
คุณสามารถเข้าถึงวิธีสแตติกได้innerTest()
ดังนี้:
Outer.Inner.innerTest();
อย่างไรก็ตามหากInner
ไม่ใช่แบบคงที่ไม่มีวิธีแบบคงที่ในการอ้างอิงวิธีinnertest
นี้ คลาสภายในที่ไม่คงที่นั้นเชื่อมโยงกับอินสแตนซ์เฉพาะของคลาสภายนอก ฟังก์ชั่นจะแตกต่างจากค่าคงที่ซึ่งการอ้างอิงถึงOuter.Inner.CONSTANT
ถูกรับประกันว่าจะไม่คลุมเครือในลักษณะที่การเรียกใช้ฟังก์ชันOuter.Inner.staticFunction();
ไม่ได้ สมมติว่าคุณมีInner.staticFunction()
สายgetState()
ที่กำหนดไว้Outer
ซึ่งถูกกำหนดไว้ในหากคุณพยายามที่จะเรียกใช้ฟังก์ชั่นแบบคงที่ตอนนี้คุณมีการอ้างอิงที่ไม่ชัดเจนกับชั้นใน นั่นคือในกรณีของคลาสภายในที่คุณเรียกใช้ฟังก์ชันสแตติก มันเป็นเรื่องสำคัญ ดูว่าไม่มีวิธีที่คงที่อย่างแท้จริงในการอ้างอิงวิธีการคงที่เนื่องจากการอ้างอิงโดยนัยไปยังวัตถุด้านนอก
Paul Bellora ถูกต้องที่นักออกแบบภาษาสามารถอนุญาตได้ จากนั้นพวกเขาจะต้องไม่อนุญาตการเข้าถึงการอ้างอิงโดยนัยถึงคลาสภายนอกในวิธีการคงที่ของคลาสภายในที่ไม่คงที่อย่างระมัดระวัง ณ จุดนี้สิ่งที่มีค่านี้เป็นชั้นในถ้าคุณไม่สามารถอ้างอิงชั้นนอกยกเว้นคงที่? และถ้าการเข้าถึงแบบสแตติกนั้นดีแล้วทำไมไม่ประกาศคลาสภายในทั้งหมดแบบสแตติก? ถ้าคุณทำให้คลาสภายในคงที่คุณก็ไม่ต้องมีการอ้างอิงโดยนัยกับคลาสภายนอกและคุณไม่มีความกำกวมนี้อีกต่อไป
หากคุณต้องการวิธีการคงที่ในชั้นเรียนแบบไม่คงที่จริงๆแล้วคุณอาจต้องพิจารณาการออกแบบของคุณใหม่
Outer.Inner i = new Outer().new Inner();
นอกจากนี้คลาสภายในยังได้รับอนุญาตให้ประกาศค่าคงที่แบบคงที่ตาม JLS §15.28
Outer.Inner.staticMethod()
Outer.Inner.CONSTANT
"คุณไม่สามารถเข้าถึง ... อินสแตนซ์ของคลาสภายในที่ไม่คงที่โดยไม่ต้องผ่านอินสแตนซ์ของคลาสภายนอก" ทำไมคุณต้องการอินสแตนซ์? คุณไม่จำเป็นต้องตัวอย่างของการเรียกร้องOuter
Outer.staticMethod()
ฉันรู้ว่านี่เป็น nitpicky แต่ประเด็นของฉันคือมันไม่เหมาะสมที่จะวางกรอบคำตอบของคุณด้วยวิธีนี้ IMHO นักออกแบบภาษาสามารถอนุญาตได้หากพวกเขาต้องการ
Outer.Inner.CONSTANT
และOuter.Inner.staticMethod()
คือการอ้างอิงถึงค่าคงที่ไม่มีโอกาสที่จะอ้างอิงถึงอินสแตนซ์Outer
ที่Inner
มีอินสแตนซ์ การอ้างอิงทั้งหมดเพื่อOuter.staticMethod()
แบ่งปันสถานะที่แน่นอนเดียวกัน การอ้างอิงทั้งหมดเพื่อOuter.Inner.CONSTANT
แบ่งปันสถานะที่แน่นอนเดียวกัน อย่างไรก็ตามการอ้างอิงไปยังOuter.Inner.staticMethod()
มีความคลุมเครือที่: "คงที่" Inner
รัฐไม่คงที่อย่างแท้จริงเนื่องจากการอ้างอิงโดยปริยายชั้นนอกในกรณีของแต่ละ ไม่มีวิธีที่ชัดเจนในการเข้าถึง
Outer.this
ที่เกี่ยวข้องกับการไม่สามารถที่จะดูที่สนามอินสแตนซ์โดยปริยาย ฉันเห็นด้วยกับนักออกแบบภาษาจาวาว่าไม่มีเหตุผลที่จะอนุญาตให้ใช้วิธีการคงที่หรือไม่คงที่เขตข้อมูลสุดท้ายในชั้นเรียนชั้นในเพราะทุกอย่างในชั้นภายในควรอยู่ในบริบทของชั้นล้อมรอบ
ฉันมีทฤษฎีซึ่งอาจหรืออาจไม่ถูกต้อง
ก่อนอื่นคุณควรรู้บางสิ่งเกี่ยวกับวิธีใช้คลาสภายในใน Java สมมติว่าคุณมีคลาสนี้:
class Outer {
private int foo = 0;
class Inner implements Runnable {
public void run(){ foo++; }
}
public Runnable newFooIncrementer(){ return new Inner(); }
}
เมื่อคุณคอมไพล์มันโค้ดที่สร้างขึ้นจะมีลักษณะเหมือนกับว่าคุณเขียนอะไรแบบนี้:
class Outer {
private int foo = 0;
static class Inner implements Runnable {
private final Outer this$0;
public Inner(Outer outer){
this$0 = outer;
}
public void run(){ this$0.foo++; }
}
public Runnable newFooIncrementer(){ return new Inner(this); }
}
ทีนี้ถ้าเราอนุญาตวิธีการแบบสแตติกในคลาสภายในแบบไม่คงที่คุณอาจต้องการทำสิ่งนี้
class Outer {
private int foo = 0;
class Inner {
public static void incrFoo(){ foo++; }
}
}
... ซึ่งดูสมเหตุสมผลพอสมควรเนื่องจากInner
คลาสดูเหมือนจะมีหนึ่งชาติต่อหนึ่งOuter
อินสแตนซ์ แต่อย่างที่เราเห็นข้างต้นคลาสภายในที่ไม่คงที่นั้นเป็นเพียงน้ำตาลซินแทคติคสำหรับคลาส "ภายใน" แบบคงที่ดังนั้นตัวอย่างสุดท้ายจะเทียบเท่ากับ:
class Outer {
private int foo = 0;
static class Inner {
private final Outer this$0;
public Inner(Outer outer){
this$0 = outer;
}
public static void incrFoo(){ this$0.foo++; }
}
}
... ซึ่งไม่สามารถใช้งานได้อย่างชัดเจนเนื่องจากthis$0
ไม่คงที่ การเรียงลำดับนี้อธิบายว่าทำไมไม่อนุญาตให้ใช้วิธีการคงที่ (แม้ว่าคุณสามารถสร้างอาร์กิวเมนต์ที่คุณสามารถอนุญาตให้ใช้วิธีการแบบคงที่ตราบใดที่พวกเขาไม่ได้อ้างอิงวัตถุที่ปิดล้อม) และทำไมคุณไม่สามารถมีเขตข้อมูลคงที่ไม่ใช่ครั้งสุดท้าย มันจะตอบโต้ได้ง่ายหากอินสแตนซ์ของคลาสภายในที่ไม่คงที่จากวัตถุต่าง ๆ ที่ใช้ร่วมกัน "สถานะคงที่") นอกจากนี้ยังอธิบายว่าทำไมเขตสุดท้ายจะได้รับอนุญาต (ตราบเท่าที่พวกเขาไม่ได้อ้างอิงวัตถุล้อมรอบ)
public static double sinDeg(double theta) { ... }
คลาสคณิตศาสตร์อรรถประโยชน์ชั้นใน?
เหตุผลเดียวคือ "ไม่ต้อง" ดังนั้นทำไมต้องสนใจที่จะสนับสนุน?
วากยสัมพันธ์ไม่มีเหตุผลที่จะห้ามไม่ให้ชั้นในจากการมีสมาชิกแบบคงที่ แม้ว่าอินสแตนซ์ของInner
จะเชื่อมโยงกับอินสแตนซ์ของOuter
ก็ยังคงเป็นไปได้ที่จะใช้Outer.Inner.myStatic
เพื่ออ้างอิงสมาชิกคงที่ของInner
ถ้าจาวาตัดสินใจที่จะทำเช่นนั้น
หากคุณต้องการแบ่งปันบางสิ่งในทุกกรณีของInner
คุณก็สามารถทำให้พวกเขาOuter
เป็นสมาชิกแบบคงที่ สิ่งนี้ไม่ได้เลวร้ายยิ่งไปกว่าการที่คุณใช้สมาชิกแบบสแตติกInner
ซึ่งOuter
ยังคงสามารถเข้าถึงสมาชิกส่วนตัวใด ๆ ได้Inner
(ไม่ปรับปรุง encapsulation)
หากคุณต้องการแบ่งปันบางสิ่งในทุก ๆ อินสแตนซ์ที่Inner
สร้างโดยouter
วัตถุหนึ่งชิ้นมันเหมาะสมกว่าที่จะทำให้พวกเขาอยู่ในOuter
ชั้นเรียนในฐานะสมาชิกสามัญ
ฉันไม่เห็นด้วยกับความคิดเห็นที่ว่า "คลาสที่ซ้อนกันแบบสแตติกนั้นเป็นเพียงแค่ระดับบนสุด" ฉันคิดว่ามันดีกว่าที่จะพิจารณาคลาสที่ซ้อนกันแบบคงที่ / ชั้นในเป็นส่วนหนึ่งของคลาสนอกเพราะพวกเขาสามารถเข้าถึงสมาชิกส่วนตัวของคลาสภายนอกได้ และสมาชิกของคลาสภายนอกคือ "สมาชิกของชั้นใน" เช่นกัน ดังนั้นไม่จำเป็นต้องสนับสนุนสมาชิกแบบคงที่ในชั้นภายใน สมาชิกสามัญ / คงที่ในชั้นนอกจะพอเพียง
จาก: https://docs.oracle.com/javase/tutorial/java/javaOO/nested.html
เช่นเดียวกับวิธีการและตัวแปรอินสแตนซ์คลาสภายในมีความสัมพันธ์กับอินสแตนซ์ของคลาสที่ล้อมรอบและมีการเข้าถึงโดยตรงกับวิธีการและเขตข้อมูลของวัตถุนั้น นอกจากนี้เนื่องจากคลาสภายในเชื่อมโยงกับอินสแตนซ์จึงไม่สามารถกำหนดสมาชิกแบบสแตติกได้
คำอธิบายของ Oracle นั้นผิวเผินและเป็นคลื่น เนื่องจากไม่มีเหตุผลทางเทคนิคหรือวากยสัมพันธ์ในการจองสมาชิกแบบคงที่ภายในคลาสภายใน (อนุญาตในภาษาอื่นเช่น C #) แรงจูงใจของนักออกแบบ Java จึงน่าจะเป็นเรื่องของแนวคิดและ / หรือเรื่องความสะดวกสบายทางเทคนิค
นี่คือการเก็งกำไรของฉัน:
แตกต่างจากคลาสระดับบนสุดคลาสภายในขึ้นอยู่กับอินสแตนซ์อินสแตนซ์ชั้นในนั้นเชื่อมโยงกับอินสแตนซ์ของคลาสภายนอกทุกคลาสและมีการเข้าถึงโดยตรงกับสมาชิกของพวกเขา นี่คือแรงจูงใจหลักสำหรับการมีใน Java แสดงอีกวิธีหนึ่ง: คลาสภายในมีความหมายสำหรับการสร้างอินสแตนซ์ในบริบทของอินสแตนซ์ของคลาสภายนอก หากไม่มีคลาสภายนอก, คลาสภายในไม่ควรใช้งานได้มากกว่าสมาชิกอินสแตนซ์อื่นของคลาสภายนอก ลองอ้างถึงสิ่งนี้ว่าเป็นวิญญาณที่พึ่งพาได้ของคลาสภายใน
ธรรมชาติของสมาชิกแบบสแตติก (ซึ่งไม่ใช่แบบเชิงวัตถุ) ขัดแย้งกับอินสแตนซ์ที่ขึ้นอยู่กับวิญญาณของคลาสภายใน (ซึ่งเป็นแบบวัตถุ) เนื่องจากคุณสามารถอ้างอิง / เรียกสมาชิกแบบสแตติกของคลาสภายในโดยไม่มีอินสแตนซ์คลาสภายนอกโดย ใช้ชื่อคลาสภายในที่ผ่านการรับรอง
ตัวแปรคงที่โดยเฉพาะอย่างยิ่งอาจทำให้ขุ่นเคืองในวิธีอื่น: สองอินสแตนซ์ของคลาสภายในที่เกี่ยวข้องกับอินสแตนซ์ต่าง ๆ ของคลาสภายนอกจะใช้ตัวแปรแบบคงที่ เนื่องจากตัวแปรเป็นองค์ประกอบของรัฐอินสแตนซ์ของคลาสภายในทั้งสองจะส่งผลให้สถานะการแบ่งใช้เป็นอิสระจากอินสแตนซ์ของคลาสภายนอกที่สัมพันธ์กับ ไม่ใช่ว่ายอมรับไม่ได้ว่าตัวแปรแบบสแตติกทำงานด้วยวิธีนี้ (เรายอมรับพวกเขาในภาษาจาวาว่ามีการประนีประนอมต่อความบริสุทธิ์ของ OOP) แต่มีความผิดที่จะต้องมีความผิดลึกกว่าโดยอนุญาตให้พวกมันอยู่ในคลาสภายใน โดยการออกแบบ. ห้ามสมาชิกสแตติกภายในคลาสภายในเพื่อสนับสนุนวิญญาณที่ขึ้นกับอินสแตนซ์ได้รับโบนัสเพิ่มจากการจอง OOP ที่ผิดมากกว่านี้
ในทางตรงกันข้ามไม่มีการกระทำผิดกฎหมายดังกล่าวโดยค่าคงที่แบบคงที่ซึ่งไม่ได้มีความหมายว่าเป็นสถานะของรัฐและสิ่งเหล่านี้จะได้รับอนุญาต ทำไมไม่ห้ามคงที่คงที่เพื่อความมั่นคงสูงสุดกับจิตวิญญาณเช่นขึ้นอยู่กับ ? อาจเป็นเพราะค่าคงที่ไม่จำเป็นต้องใช้หน่วยความจำมากกว่าที่จำเป็น (ถ้าพวกเขาถูกบังคับให้ไม่คงที่พวกเขาจะถูกคัดลอกไปยังอินสแตนซ์ของคลาสภายในซึ่งอาจสิ้นเปลือง) มิฉะนั้นฉันก็ไม่สามารถจินตนาการได้ว่าเหตุผลสำหรับข้อยกเว้น
อาจไม่ใช่เหตุผลที่มั่นคง แต่ IMO ทำให้เข้าใจถึงคำพูดคร่าวๆของออราเคิลในเรื่องนี้ได้มากที่สุด
คำตอบสั้น ๆ : โมเดลจิตโปรแกรมเมอร์ส่วนใหญ่มีขอบเขตการทำงานอย่างไรไม่ใช่โมเดลที่ใช้โดย javac การจับคู่โมเดลที่ใช้งานง่ายยิ่งขึ้นนั้นจำเป็นต้องมีการเปลี่ยนแปลงครั้งใหญ่ในการทำงานของ javac
เหตุผลหลักที่สมาชิกแบบคงที่ในชั้นเรียนภายในเป็นที่พึงประสงค์คือเพื่อความสะอาดของรหัส - สมาชิกแบบคงที่ที่ใช้โดยเฉพาะในชั้นเรียนควรจะอยู่ภายในมันแทนที่จะต้องอยู่ในชั้นนอก พิจารณา:
class Outer {
int outID;
class Inner {
static int nextID;
int id = nextID++;
String getID() {
return outID + ":" + id;
}
}
}
พิจารณาสิ่งที่เกิดขึ้นใน getID () เมื่อฉันใช้ตัวระบุที่ไม่มีเงื่อนไข "outID" ขอบเขตที่ตัวระบุนี้ปรากฏขึ้นมีลักษณะดังนี้:
Outer -> Inner -> getID()
ที่นี่อีกครั้งเพราะนี่เป็นเพียงวิธีการทำงานของ javac ระดับ "Outer" ของขอบเขตประกอบด้วยสมาชิกทั้งแบบสแตติกและอินสแตนซ์ของ Outer นี่คือความสับสนเพราะเรามักจะบอกให้คิดว่าส่วนคงที่ของชั้นเรียนเป็นระดับอื่นของขอบเขต:
Outer static -> Outer instance -> instanceMethod()
\----> staticMethod()
ในวิธีการคิดเกี่ยวกับเรื่องนี้แน่นอน staticMethod () สามารถเห็นสมาชิกคงที่ของ Outer แต่ถ้านั่นเป็นวิธีการทำงานของ javac การอ้างอิงตัวแปรอินสแตนซ์ในวิธีการแบบคงที่จะส่งผลให้เกิดข้อผิดพลาด "ชื่อไม่สามารถแก้ไขได้" สิ่งที่เกิดขึ้นจริงคือชื่อพบในขอบเขต แต่จากนั้นระดับการตรวจสอบเพิ่มเติมจะเริ่มขึ้นและแสดงให้เห็นว่าชื่อถูกประกาศในบริบทอินสแตนซ์และถูกอ้างอิงจากบริบทแบบคงที่
ตกลงสิ่งนี้เกี่ยวข้องกับคลาสภายในอย่างไร อย่างไร้เดียงสาเราคิดว่าไม่มีเหตุผลในการเรียนภายในไม่สามารถมีขอบเขตคงที่เพราะเรากำลังภาพขอบเขตการทำงานเช่นนี้:
Outer static -> Outer instance -> Inner instance -> getID()
\------ Inner static ------^
กล่าวอีกนัยหนึ่งการประกาศแบบสแตติกในคลาสภายในและการประกาศอินสแตนซ์ในคลาสภายนอกนั้นอยู่ในขอบเขตภายในบริบทอินสแตนซ์ของคลาสชั้นใน ทั้งสองซ้อนกันอยู่ในขอบเขตคงที่ของ Outer
นั่นไม่ใช่วิธีการทำงานของ javac - มีขอบเขตระดับเดียวสำหรับสมาชิกแบบสแตติกและอินสแตนซ์และขอบเขตจะทำรังอย่างเคร่งครัดเสมอ แม้แต่การสืบทอดจะถูกนำไปใช้โดยการคัดลอกการประกาศในคลาสย่อยแทนการแยกและค้นหาขอบเขตซูเปอร์คลาส
เพื่อสนับสนุนสมาชิกแบบคงที่ของคลาสภายใน javac จะต้องแยกขอบเขตแบบคงที่และอินสแตนซ์และสนับสนุนการแยกสาขาและเข้าร่วมลำดับชั้นของขอบเขตหรือจะต้องขยายแนวคิดแบบ "บริบทบริบท" แบบบูลแบบง่าย ๆ เพื่อเปลี่ยนชนิดของบริบทในทุกระดับ ของคลาสที่ซ้อนกันในขอบเขตปัจจุบัน
ทำไมเราไม่สามารถมีวิธีสแตติกในคลาสภายในที่ไม่คงที่ได้?
หมายเหตุ:คลาสที่ซ้อนกันแบบไม่คงที่เรียกว่าคลาสภายในดังนั้นคุณจึงไม่มีnon-static inner class
เช่นนั้น
อินสแตนซ์ของคลาสภายในไม่มีอยู่โดยไม่มีอินสแตนซ์ที่สอดคล้องกันของคลาสภายนอก คลาสภายในไม่สามารถประกาศสมาชิกแบบคงที่นอกเหนือจากค่าคงที่เวลาคอมไพล์ static
ถ้ามันไม่ได้รับอนุญาตจากนั้นก็จะได้รับความคลุมเครือเกี่ยวกับความหมายของ ในกรณีนั้นจะมีความสับสน:
นั่นคือเหตุผลที่นักออกแบบอาจตัดสินใจไม่จัดการกับปัญหานี้เลย
ถ้าฉันทำให้ชั้นในคงที่มันใช้งานได้ ทำไม
คุณไม่สามารถสร้างคลาสภายในให้คงที่ได้ แต่คุณสามารถประกาศคลาสคงที่ว่าซ้อนกัน ในกรณีนี้คลาสที่ซ้อนกันนี้เป็นส่วนหนึ่งของคลาสภายนอกและสามารถมีสมาชิกแบบสแตติกโดยไม่มีปัญหาใด ๆ
หัวข้อนี้ได้รับความสนใจจากหลาย ๆ คน แต่ฉันจะพยายามอธิบายด้วยคำศัพท์ที่ง่ายที่สุด
ประการแรกด้วยการอ้างอิงถึงhttp://docs.oracle.com/javase/specs/jls/se7/html/jls-12.html#jls-12.4.1คลาสหรืออินเทอร์เฟซจะเริ่มต้นได้ทันทีก่อนที่จะเกิดขึ้น / เรียกใช้ครั้งแรก ของสมาชิกใด ๆ ซึ่งนำหน้าด้วยคำหลักแบบคงที่
ดังนั้นถ้าเราใส่สมาชิกแบบคงที่ภายในคลาสภายในมันจะนำไปสู่การเริ่มต้นของคลาสภายในไม่จำเป็นต้องเป็นคลาสภายนอก / ปิดล้อม ดังนั้นเราจึงขัดขวางลำดับการเริ่มต้นของคลาส
พิจารณาความจริงที่ว่าคลาสภายในที่ไม่คงที่นั้นเชื่อมโยงกับอินสแตนซ์ของคลาสที่ล้อมรอบ / ภายนอก ดังนั้นการเชื่อมโยงกับอินสแตนซ์จะหมายถึงว่าคลาสภายในจะอยู่ในอินสแตนซ์ของคลาสภายนอกและจะแตกต่างกันระหว่างอินสแตนซ์
ลดความซับซ้อนของจุดเพื่อเข้าถึงสมาชิกแบบคงที่เราต้องการอินสแตนซ์ของคลาสภายนอกซึ่งเราจะต้องสร้างอินสแตนซ์ของคลาสภายในแบบไม่คงที่อีกครั้ง สมาชิกแบบคงที่ไม่ควรถูกผูกไว้กับอินสแตนซ์และดังนั้นคุณได้รับข้อผิดพลาดในการคอมไพล์
คลาสภายในเป็นสิ่งที่แตกต่างอย่างสิ้นเชิงจากคลาสที่ซ้อนกันแบบสแตติกแม้ว่าทั้งคู่จะคล้ายกันในไวยากรณ์ คลาสที่ซ้อนกันแบบสแตติกเป็นเพียงวิธีสำหรับการจัดกลุ่มในขณะที่คลาสภายในมีความสัมพันธ์ที่ดี - และการเข้าถึงค่าทั้งหมดของ - คลาสภายนอก คุณควรแน่ใจว่าทำไมคุณถึงต้องการใช้ชั้นในและจากนั้นควรเป็นธรรมชาติที่คุณต้องใช้ ถ้าคุณต้องการประกาศเมธอดสแตติกอาจเป็นคลาสที่ซ้อนกันแบบสแตติกที่คุณต้องการ
สมมติว่ามีสองกรณีของคลาสนอกและพวกเขาทั้งสองมีอินสแตนซ์ชั้นภายในตอนนี้ถ้าชั้นในมีสมาชิกคงที่แล้วมันจะเก็บสำเนาของสมาชิกนั้นเพียงหนึ่งในพื้นที่กองในกรณีนี้วัตถุทั้งชั้นนอกจะอ้างถึงนี้ สำเนาเดียว & พวกเขาสามารถแก้ไขได้ด้วยกันซึ่งอาจทำให้สถานการณ์ "สกปรกอ่าน" ดังนั้นเพื่อป้องกัน Java นี้ได้ใช้ข้อ จำกัด นี้จุดแข็งอีกประการหนึ่งเพื่อสนับสนุนอาร์กิวเมนต์นี้คือ Java อนุญาตให้สมาชิกแบบคงที่สุดท้ายที่นี่ เปลี่ยนจากวัตถุชั้นนอกอย่างใดอย่างหนึ่ง โปรดให้ฉันถ้าฉันผิด
ก่อนอื่นทำไมใครบางคนต้องการกำหนดสมาชิกแบบคงที่ในชั้นในแบบไม่คงที่? คำตอบคือเพื่อให้สมาชิกชั้นนอกสามารถใช้สมาชิกคงที่ที่มีชื่อชั้นในเท่านั้นใช่มั้ย
แต่สำหรับกรณีนี้เราสามารถกำหนดสมาชิกโดยตรงในคลาสภายนอก ซึ่งจะเชื่อมโยงกับวัตถุทั้งหมดของชั้นภายในภายในอินสแตนซ์ชั้นนอก
ชอบรหัสด้านล่าง
public class Outer {
class Inner {
public static void method() {
}
}
}
สามารถเขียนได้เช่นนี้
public class Outer {
void method() {
}
class Inner {
}
}
ดังนั้นในความคิดของฉันที่จะไม่ซับซ้อนนักออกแบบโค้ดจาวาไม่อนุญาตให้ใช้งานฟังก์ชันนี้หรือเราอาจเห็นฟังก์ชั่นนี้ในรุ่นต่อไปที่มีคุณสมบัติเพิ่มเติม
พยายามที่จะรักษาระดับเป็นสนามปกติแล้วคุณจะเข้าใจ
//something must be static. Suppose something is an inner class, then it has static keyword which means it's a static class
Outer.something
มันไม่มีประโยชน์ที่จะให้สมาชิกชั้นในคงที่เพราะคุณจะไม่สามารถเข้าถึงพวกเขาได้ตั้งแต่แรก
คิดเกี่ยวกับสิ่งนี้เพื่อเข้าถึงสมาชิกแบบคงที่คุณใช้ className.memberName ,, ในกรณีของเรามันควรเป็นสิ่งที่ต้องการ
คุณได้รับอนุญาตวิธีการคงที่ในชั้นเรียนที่ซ้อนกันคงที่ ตัวอย่างเช่น
public class Outer {
public static class Inner {
public static void method() {
}
}
}