It's not really about replacing the implementation.
Depending on interfaces means you (by definition) can't depend on the implementation. It's a decoupling thing more than anything else. You get some benefits for mocking during testing and so on but it's mostly just to get something like a C++-style class declaration/definition (or .h/.cpp)-split.
It's admittedly taken a bit too far in some codebases and often done without much thought to why, but it's also a bit of an artifact of pre Jigsaw-era Java where it was very hard to enforce boundaries between modules. In that light it makes at least some sense.
Depending on interfaces means you (by definition) can't depend on the implementation. It's a decoupling thing more than anything else. You get some benefits for mocking during testing and so on but it's mostly just to get something like a C++-style class declaration/definition (or .h/.cpp)-split.
It's admittedly taken a bit too far in some codebases and often done without much thought to why, but it's also a bit of an artifact of pre Jigsaw-era Java where it was very hard to enforce boundaries between modules. In that light it makes at least some sense.