Na verdade cara… o acesso ao banco é feito por uma classe que pode ser denominada (e geralmente é) de ConnectionManager. Lá, você obtém a conexão com o banco e etc.
O que acontece com o DAO é a vantagem de se ter uma interface onde se pode definir métodos de persistência nos dados que são comuns para todas as classes do seu sistema. Exemplo: save, update, delete, etc…
E quando você vai programar Orientado a Objetos, vc tem que pensar orientado à objetos. Ou seja, você não tem que pensar que vc está gravando um registro em uma tupla de uma tabela de um banco de dados. Você tem que pensar que você está gravando um OBJETO dentro de uma tabela do banco de dados. Por isso que a abordagem de que o método salvaContato() tem que receber um objeto do tipo Contato como parâmetro é totalmente correta e dentro dos padrões da POO.
Como vc deve ter percebido, a classe DAO é uma INTERFACE e os “beans” de cada uma das classes que mapeiam entidades da sua base de dados devem implementá-la.
Ou seja, vc vai ter a classe Contato (que representa sua entidade do banco de dados), a classe ContatoDB (o seu bean, que implementa DAO e define como os métodos da interface serão utilizados) e a Interface ContatoDAO, que vai conter a especificação dos métodos comuns para todos os beans.
Quando vc quiser salvar um objeto na base de dados, vc setará os atributos da classe Contato e acessará o método save(Contato contato) que está dentro da sua Classe ContatoDB…
ContatoDAO dao = new ContatoDB();
aqui, você armazena no heap do java, uma variável do tipo ContatoDAO, que possui os métodos contidos na interface, porém, a execução dos mesmos, é feita dentro da classe ContatoDB, pois ela implementa sua DAO.
Resumindo, cada classe vai ter a sua função direitinho…
a ConnectionManager vai obter a conexão com o banco de dados
a Contato vai mapear sua entidade do banco de dados
a ContatoDAO vai definir todos os métodos de persistência que estarão disponíveis para utilização (de modo que haja um padrão para todas as classes que a implementam)
e a ContatoDB vai realizar a implementação desta interface, sobrescrevendo os métodos definidos na interface, utilizando-os de acordo com suas regras de negócio e obdecendo a definição da tabela “Contato” do seu banco de dados (ou seja, no final das contas, apenas ESSA CLASSE vai conhecer sua tabela no banco de dados).
Espero ter ajudado…