apakah teks mengenai penggantian dan penyembunyian metode di docs.Oracle.com bersifat ambigu?

Saya membaca tentang mengganti dan menyembunyikan metode di situs web docs.Oracle.com (https://docs.Oracle.com/javase/tutorial/java/IandI/override.html). Di bawah judul 'Metode Statis', Oracle dengan senang hati merangkumnya untuk kami:

"Perbedaan antara menyembunyikan metode statis dan mengganti metode instan mempunyai implikasi penting:

  • Versi metode instance yang diganti yang dipanggil adalah versi yang ada di subkelas.
  • Versi metode statis tersembunyi yang dipanggil bergantung pada apakah metode tersebut dipanggil dari superkelas atau subkelas."

Poin pertama sangat jelas. Poin kedua juga terkesan sangat informatif, namun saat saya membacanya kembali, sepertinya saya menjadi bingung.

Dari sudut pandang saya, sepertinya setiap metode statis di superkelas dan subkelas disembunyikan, dan dengan pengikatan awal (pengikatan waktu kompilasi), metode yang sesuai dipilih dan metode lainnya disembunyikan. Ini dipilih berdasarkan tipe referensi dari variabel tempat Anda memanggilnya. Namun rumusan kalimat pada poin kedua membuat seolah-olah kompiler memperlakukan kedua metode ini sebagai satu karena keduanya memiliki tanda tangan yang sama, dan memiliki versi super dan versi sub, dibandingkan harus memisahkan metode tersembunyi dan memilih yang sesuai. .

pertanyaan saya adalah yang mana dari dua sudut ini yang benar (kedua metode disembunyikan atau satu metode dengan dua versi karena tanda tangan metode), dan apakah penting yang mana yang saya pikirkan? bonus: apakah pemikiran umum saya tentang subjek ini benar?

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 sumber


Jawaban (1)


Dari sudut pandang saya sepertinya kedua metode statis di superkelas dan subkelas disembunyikan, dan dengan pengikatan awal (pengikatan waktu kompilasi), metode yang sesuai dipilih dan yang lainnya disembunyikan.

Untuk di bawah ini, pertimbangkan kode ini:

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()
    }
}

Ada dua kasus yang perlu dipertimbangkan:

  • Dua metode testSuper(): Memanggil metode dari "dalam" SuperClass, atau memanggil metode dari "luar" dengan memenuhi syarat dengan SuperClass.

    Dalam hal ini, tidak ada yang disembunyikan. Anda dapat menghubungi a() dan b() di SuperClass.

    Metode di SubClass tidak dianggap tersembunyi, karena jelas-jelas tidak ada dalam cakupannya.

  • Dua metode testSub(): Memanggil metode dari "dalam" SubClass, atau memanggil metode dari "luar" dengan memenuhi syarat dengan SubClass.

    Dalam hal ini, keempat metode berada dalam cakupan, tetapi metode b() di SuperClass disembunyikan.

Seperti yang Anda lihat, hanya b() di SuperClass yang dianggap tersembunyi. Angka b() di SubClass tidak pernah disembunyikan.

person Andreas    schedule 22.08.2019