There are 3 main reasons, IMO:
First reason: proxies.
If you ask Spring for the bean of type UserDAO, it will in fact return a proxy encapsulating the actual UserDAOImpl instance. This allows it to demarcate transactions, verify security authorization, log accesses, compute statistics, etc. It's possible to do it without an interface, but then byte-code manipulation is needed.
Second reasons: testability.
When unit-testing a business service which uses a UserDAO, you typically inject a mock UserDAO implementation. Once again, this is easier to do when UserDAO is an interface. It's possible with a concrete class, but it has not always been, and it's still easier with an interface
Third reason: decoupling.
By using an interface, you have a place where you define the real contract of the DAO for its clients. Sure, it needs a setDataSource()
method in the concrete implementation, but clients don't care about that. All they need is set of data-access methods offered by the DAO. By separating the interface and the concrete implementation, you make sure that the client doesn't rely on implementation details of the DAO.
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…