ข้อความเกี่ยวกับวิธีการแทนที่และซ่อนบน docs.oracle.com มีความคลุมเครือหรือไม่

ฉันกำลังอ่านเกี่ยวกับวิธีการแทนที่และการซ่อนบนเว็บไซต์ docs.oracle.com (https://docs.oracle.com/javase/tutorial/java/IandI/override.html) ภายใต้หัวข้อ 'วิธีการแบบคงที่' Oracle กรุณาสรุปให้เราทราบ:

"ความแตกต่างระหว่างการซ่อนวิธีการแบบคงที่และการแทนที่วิธีการแบบอินสแตนซ์มีผลกระทบที่สำคัญ:

  • เวอร์ชันของเมธอดอินสแตนซ์ที่ถูกแทนที่ที่ถูกเรียกใช้นั้นเป็นเวอร์ชันในคลาสย่อย
  • เวอร์ชันของเมธอดสแตติกที่ซ่อนอยู่ซึ่งถูกเรียกใช้นั้นขึ้นอยู่กับว่ามันถูกเรียกใช้จากซูเปอร์คลาสหรือคลาสย่อย"

สัญลักษณ์แสดงหัวข้อย่อยแรกมีความชัดเจนมาก สัญลักษณ์แสดงหัวข้อย่อยที่สองดูเหมือนมีข้อมูลมาก แต่เมื่ออ่านซ้ำฉันรู้สึกสับสน

จากมุมมองของฉัน ดูเหมือนว่าแต่ละวิธีแบบสแตติกในทั้งซูเปอร์คลาสและคลาสย่อยจะถูกซ่อนไว้ และโดยการผูกล่วงหน้า (การรวมเวลาคอมไพล์) วิธีการที่เหมาะสมจะถูกเลือก และอีกวิธีหนึ่งจะถูกซ่อนไว้ สิ่งนี้ถูกเลือกโดยประเภทการอ้างอิงของตัวแปรที่คุณเรียกใช้ อย่างไรก็ตาม การกำหนดประโยคในสัญลักษณ์แสดงหัวข้อย่อยที่สองทำให้ดูเหมือนว่าคอมไพลเลอร์จะถือว่าทั้งสองวิธีนี้เป็นหนึ่งเดียวเนื่องจากมีลายเซ็นเดียวกัน และมีเวอร์ชัน super และเวอร์ชันย่อย ซึ่งตรงกันข้ามกับการแยกวิธีการที่ซ่อนอยู่และเลือกวิธีที่เหมาะสม .

คำถามของฉันคือมุมใดในสองมุมนี้ที่ถูกต้อง (ทั้งสองวิธีถูกซ่อนหรือวิธีเดียวที่มีสองเวอร์ชันเนื่องจากลายเซ็นของวิธีการ) และมันสำคัญไหมที่ฉันคิดเกี่ยวกับอันไหน โบนัส: ความคิดทั่วไปของฉันเกี่ยวกับเรื่องนี้ถูกต้องหรือไม่?

public class Animal {
    public static void testClassMethod() {
        System.out.println("The static method in Animal");
    }
    public void testInstanceMethod() {
        System.out.println("The instance method in Animal");
    }
}

public class Cat extends Animal {
    public static void testClassMethod() {
        System.out.println("The static method in Cat");
    }
    public void testInstanceMethod() {
        System.out.println("The instance method in Cat");
    }

    public static void main(String[] args) {
        Cat myCat = new Cat();
        Animal myAnimal = myCat;
        Animal.testClassMethod();
        myAnimal.testInstanceMethod();
    }
}

//The static method in Animal
//The instance method in Cat

person Zillah    schedule 22.08.2019    source แหล่งที่มา


คำตอบ (1)


จากมุมมองของฉัน ดูเหมือนว่าทั้งวิธีการคงที่ในทั้งซูเปอร์คลาสและคลาสย่อยถูกซ่อนอยู่ และโดยการผูกล่วงหน้า (การรวมเวลาคอมไพล์) วิธีการที่เหมาะสมจะถูกเลือก และอีกวิธีหนึ่งจะถูกซ่อนไว้

สำหรับด้านล่าง ให้พิจารณาโค้ดนี้:

class SuperClass {
    static void a() { System.out.println("SuperClass.a()"); }
    static void b() { System.out.println("SuperClass.b()"); }
    void testSuper() { // Call from "inside" SuperClass
        a(); // calls SuperClass.a()
        b(); // calls SuperClass.b()
    }
}
class SubClass extends SuperClass {
    static void b() { System.out.println("SubClass.b()"); }
    static void c() { System.out.println("SubClass.c()"); }
    void testSub() { // Call from "inside" SubClass
        a();   // calls SuperClass.a().
        b();   // calls SubClass.b().
        c();   // calls SubClass.c()
    }
}
class Test {
    void testSuper() { // Call SuperClass from "outside"
        SuperClass.a(); // calls SuperClass.a()
        SuperClass.b(); // calls SuperClass.b()
    }
    void testSub() { // Call SubClass from "outside"
        SubClass.a(); // calls SuperClass.a()
                      // IDE warning: The static method a() from the type SuperClass should be accessed directly
        SubClass.b(); // calls SubClass.b()
        SubClass.c(); // calls SubClass.c()
    }
}

มีสองกรณีที่ต้องพิจารณา:

  • วิธี testSuper() สองวิธี: การเรียกวิธีการจาก "ภายใน" SuperClass หรือการเรียกวิธีการจาก "ภายนอก" โดยมีคุณสมบัติด้วย SuperClass

    ในกรณีนี้ไม่มีอะไรถูกซ่อนไว้ คุณสามารถโทร a() และ b() ใน SuperClass

    วิธีการใน SubClass จะไม่ถือว่าถูกซ่อนไว้ เนื่องจากไม่อยู่ในขอบเขตอย่างชัดเจน

  • วิธี testSub() สองวิธี: การเรียกวิธีการจาก "ภายใน" SubClass หรือการเรียกวิธีการจาก "ภายนอก" โดยมีคุณสมบัติด้วย SubClass

    ในกรณีนี้ ทั้ง 4 วิธีอยู่ในขอบเขต แต่วิธี b() ใน SuperClass ถูกซ่อนอยู่

อย่างที่คุณเห็น เฉพาะ b() ใน SuperClass เท่านั้นที่จะถือว่าถูกซ่อน b() ใน SubClass ไม่เคย ซ่อน

person Andreas    schedule 22.08.2019