"Substituindo" métodos privados com chamada de upcasting em java

public class PrivateOverride {
    private void f() {
        System.out.println("PrivateOverride f()");
    }
    public static void main(String[] args) {
        PrivateOverride po = new DerivedWithOutD();
        po.d();// PrivateOverride f()

        PrivateOverride poD = new DerivedWithD();
        poD.d();//Derived f()
    }

    public void d() {
        f();
    }
}

class DerivedWithOutD extends PrivateOverride {
    public void f() {
        System.out.println("Derived f()");
    }
}
class DerivedWithD extends PrivateOverride {
    public void f() {
        System.out.println("Derived f()");
    }

    public void d() {
        f();
    }
}

Como os códigos acima mostram, quando DerivedWithOutD não substitui o método d (), ele chama f () pertencem a PrivateOverride, é porque o método f () de PrivateOverride não pode ser substituído? Mas o d () herda de PrivateOverride deve pertencer a DerivedWithOutD, por que d () chama o private f ()? E por que a classe DerivedWithD parece fazer a substituição E pode chamar o público de f ()? Além disso, quando altero o f () de PrivateOverride para público, tudo imprime Derivado f (), isso me confunde agora!

questionAnswers(1)

yourAnswerToTheQuestion