Zamanında okumuş olabilirim, ama pratikte sanıyorum hiç kullanmadım.
Soruyu okuyunca birkaç döküman okudum.
Method overriding ne demek zaten biliyoruz, açıklama
Method hiding diye okuyunca ilk aklıma gelen herhalde overridding yaparak methoda ait erişim belirleyiciyi değiştiriyoruz (public -> private) bu şekilde saklıyoruz olarak düşündüm. Ama kaynaklarda bu şekilde olmadığını gördüm.
Şu linkte güzel bir açıklama var.
https://stackoverflow.com/a/16313742
Kendi anladığım şekilde açıklayayım
public class Animal {
public static void foo() {
System.out.println("Animal");
}
}
public class Cat extends Animal {
public static void foo() { // hides Animal.foo()
System.out.println("Cat");
}
}
Bu sınıfların içinde tanımlı static metodlar var ve aşağıdaki kod parçasında bu static metodları olması gerektiği gibi Sınıf.Method değil de Instance.Method çağırırsak olaylar biraz değişmeye başlıyor. Tercih/tavsiye edilen Sınıf.method şeklinde çağırmak olduğunu unutmayalım.
public class Main {
public static void main(String[] args) {
System.out.print("Animal ->");
Animal.foo(); // prints Animal
System.out.print("Cat ->");
Cat.foo(); // prints Cat
Animal a = new Animal();
Animal b = new Cat();
Cat c = new Cat();
Animal d = null;
System.out.print("Animal a = Animal ->");
a.foo(); // Yapmayın
System.out.print("Animal b = Cat ->");
b.foo(); // Yapmayın
System.out.print("Cat c = Cat ->");
c.foo(); // Yapmayın
System.out.print("Null d ->");
d.foo(); // Yapmayın
}
}
Çalıştırdığımız zaman çıktı.
Animal ->Animal
Cat ->Cat
Animal a = Animal ->Animal
Animal b = Cat ->Animal
Cat c = Cat ->Cat
Null d ->Animal
Normalde metodlarımız static değil de normal metod olsaydı Animal a = Cat diye tanım yaptıktan sonra a.foo() çağırdığmızda ekrana Cat yazmalıydı. Neden çünkü instance üzerinden çağrılacaktı ve alt sınıfta (Cat) override edilecekti. O yüzden davranışı değişecekti.
Peki burada ne olmuş. Animal a = Cat satırdaki eşitliğin sol tarafı Animal olduğu için ve çağrılan metod static olduğu için sol tarafta tanımlı olan Animal sınıfının static metodunu çağırıyor. Benim beklentim aslında override olduğu için yine Cat sınıfındakini çağırması yönündeydi. Ama anlaşılabilir bir yaklaşım.
Asıl beni şaşırtan d.foo çağırdığın zaman normalde d = null olduğu için null pointer exception alması gerekiyor. Ama direk Animal.foo metodunu çağırıyor.
Bunun nedenini anlamak için kodu derledikten sonra class dosyasından decompile ettim. Sonuç aşağıdaki gibi.
public class Main {
public static void main(String[] args) {
System.out.print("Animal ->");
Animal.foo();
System.out.print("Cat ->");
Cat.foo();
Animal a = new Animal();
Animal b = new Cat();
Cat c = new Cat();
Animal d = null;
System.out.print("Animal a = Animal ->");
Animal.foo();
System.out.print("Animal b = Cat ->");
Animal.foo();
System.out.print("Cat c = Cat ->");
Cat.foo();
System.out.print("Null d ->");
Animal.foo();
}
}
Biraz dallandı :)
Sonuç static metodların davranışlarını override etme işlemine hiding deniyor gibi düşünüyorum. Aklıma başka birşey gelirse yazarım.
İyi çalışmalar,
https://www.baeldung.com/java-variable-method-hiding
http://java-decompiler.github.io/