[RESOLVIDO]Como funciona um método que retorna interface?

Bem galera, minha dúvida é o seguinte, Connection é um interface, e até onde eu sei, interface é uma espécie de contrato, em que a classe que implementa-lo, será obrigado a possuir os métodos da interface. Mais eu não entendi a lógica por exemplo "Connection con = DriverManager.getConnection(“blá blá”); onde vc passa por parâmetros a url do banco de dados, alguém poderia explicar?
Statement e ResultSet tb são interfaces que possuem métodos sem comandos e não consigo entender que quando vc atruibui por exemplo para um objeto do tipo Statement o con.preparedStatement(); que é um método da interface Connection, mais que não tem não comando!!

Isso que eu não entendi!!
Espero resposta!

Obrigado pela atenção!!!

Recurso polimorfico, quer dizer que voce pode usar qualquer objeto que implemente esta interface para receber este retorno, no final das contas seu codigo fica mais flexível e reutilizavel.

Um exemplo:

//metodo de um objeto Bola

public List retornaLista();

//posso receber da seguinte forma:

ArrayList a = Bola.retornaLista();

Isto se deve ao fato de que ArrayList implementa(é do tipo de ) List.

EDIT: Passei os olhos rapidamente sobre seu tópico e nao captei 100% da tua pergunta, agora vai:

Quando vc declara uma interface (Lembrando que declarar é diferente de criar instância), quer dizer que o objeto que você vai controlar por esta declaração só vai ter visível os métodos da interface ( Este objeto obrigatoriamente deve ser do tipo da interface), ou seja, você declara uma interface, mas ta recebendo um objeto instanciado daquele tipo (objeto concreto), que você vai poder controla-lo através dos métodos da interface (metodos estes, que obrigatoriamente estão no objeto).

falow

antes de tudo você precisa entender o conceito de “é um”.

Celular “é um” Celular? sim…

celular “é um” Telefone? sim também…

pense em telefone como por exemplo uma interface, onde você tem métodos fazerLigacao e receberLigacao. Ok, celular precisa ter estes métodos implementados, para “ser um” telefone (por que tudo o que se espera que “seja um” telefone deve fazer isso, no mínimo).

interface, é somente um contrato, entenda isso como um “tipo”, ou seja, o que deve ter la. Em um método, você pode ter o tipo de retorno como “Telefone”, mas não é um objeto Telefone que será retornado, Telefone é só uma ideia de algo que faça ligações e receba ligações, é abstrato, não é concreto. Ok, então o método que tenha o tipo de retorno Telefone, “pode” retornar um Celular, ou um Fax… ambos são classes que implementam Telefone.

Ai você me diz, ok, mas eu chamo os métodos do Telefone retornado e eles executam, mesmo Telefone sendo uma interface, portanto um tipo abstrato. O telefone que você tem não é uma instancia de telefone, é uma instancia de uma classe que “seja um” telefone, essa sim, possui os métodos implementados.

O seu objeto conn que você obteve, apesar de ser de um “tipo” Connection, na realidade é um objeto que implemente Connection, como OracleConnection por exemplo, no caso do Oracle.

Como o ganondorfan falou, o uso de interfaces torna seu sistema mais flexível e reutilizável.
podemos até estender este conceito ao TDD, onde seus Mocks de objetos são mais fáceis de
se utilizar.
E, bem grosso modo, como uma classe que implementa(implements) uma interface, esta classe
é obrigada a implementar os métodos que a interface possui!

Imaginemos a interface:

public interface Funcionario {
	public Double calculaSalario();
}

Imaginemos que temos Funcionários de dois tipos:

public class Gerente implements Funcionario{

	@Override
	public Double calculaSalario() {
		return 1000.0;
	}
}

public class Diretor implements Funcionario{

	@Override
	public Double calculaSalario() {
		return 2000.0;
	}
}

E podemos ter o teste principal:

public class Principal {
	public static void main(String[] args) {
		Funcionario funcionario = new Gerente();
		Double salarioGerente = funcionario.calculaSalario();
		System.out.println(salarioGerente);
		
		funcionario = new Diretor();
		Double salarioDiretor = funcionario.calculaSalario();
		System.out.println(salarioDiretor);
	}
}

Neste caso, todo funcionário possui um cálculo de salário por exemplo. Para o sistema, todo Gerente
deveria se comportar como Funcionario, logo a classe Gerente implementa a interface Funcionario.

No teste você tem
Funcionario funcionario = Alguma classe que implementa a interface Funcionario
ou seja, seu funcionario não aceitará nenhuma classe que não implemente a interface, pois funcionario
sabe que usará o método calcularSalario().

A partir do momento que fazemos
funcionario = new gerente()
Aí sim temos a instanciação de um objeto que possui a implementação dos métodos que estão na interface Funcionario, ou
seja, possui “código” para o método calcularSalario().

Diversos são os motivos para o desenvolvimento utilizando interfaces e o Guj também deve ter diversas
discussões sobre o tema! :slight_smile:

Isso que coloquei é bem “a grosso modo” e sorry pelo exemplo simplório!

Até mais!

Poxa, enquanto eu escrevia o maior_abandonado colaborou com a teoria também! :-o

Até mais!

Bem… eu consegui entender mais ou menos… mais não entendi por exemplo na questão de uma interface utilizar um própria interface, tipo:

Statement stm = con.creatStatement();
ResultSet rs = stm.executeQuery("blabla");

é aí que eu ainda me perco pra entender, por que tipo são tudo interface o Statement e ResultSet… será que alguém poderia me explicar essa parte melhor??? :lol:

Obrigado pela atenção!!

Cara blz, o pessoal esta sendo bem claro, pense o seguinte, quando vc chama con.createStatement() ele vai te retornar um objeto que é do tipo Statement e que dependendo das configurações que vc criou a conexão do banco vai ser o objeto para vc passar consultas para o seu banco. Se vc configurou a conexao para oracle, o createStatement vai te dar um objeto Statement para vc realizar consultas no banco oracle. Se vc configurou para Postgresql o createStatement vai te fornecer um objeto Statement para vc realizar consultas no banco Postgresql e assim para todos os outros bancos que existam. Vc precisa abstrair e entender que ele vai te dar um Statement, não uma interface, pois vc não pode instanciar uma interface, mas sim, um objeto que implementou esta interface e que dependendo das configurações da conexao, vc vai ter um Objeto do tipo Statement. O mesmo para o ResultSet.
Se não fosse assim vc teria que ter um OracleStatement, PostgresqlStatement, MysqlStatement e etc. O que o con.createStatement() faz é te dar uma forma de fazer consultas no banco. Como ele é implementado não vem ao caso ( encapsulamento ). Ok meu velho. Muitas coisas precisão ser abstraídas, entenda o que ele vai te retornar e não como faz.

Olá alexandre!

Basicamente é o seguinte:
Temos uma conexão que é a seguinte:

Connection conexao = ConexaoUtil.conecta();

Neste caso, temos o método conecta() que já possui uma implementação da interface Connection,
daí a possibilidade de podermos atribuir para a variável conexao

Agora que temos o objeto conexao , sabemos que ele implementa o método createStatement()
que “faz parte do contrato” da Interface Connection.

Resumindo:
Connection é uma interface
Statement é uma interface
createStatement() retorna um Statement, mas temos uma classe que implementa este createStatement();
O ConexaoUtil possui o método conecta(); que possui a implementação destes métodos, o código em si.

Não entendi bem o que você quis dizer com “uma interface utilizar a própria interface”.
Seria você chamar métodos direto de uma Interface?

Abraços!

Enquanto eu escrevia o nosso amigo rjbcordeiro também colocou uma teoria. :-o
Posta o que seria a “interface utilizar a própria interface” (ainda imagino
que você quis dizer a invocação dos métodos da interface) que acho que o pessoal
pode ajudar melhor.

Até mais!

Bem… ali sobre a conexão de banco de dado foi só um exemplo que eu dei… o que na verdade quero saber mesmo… é questão da interface, de tipo como criar a interface pra ser tanto reutilizado, que esse é o seu conceito e talz!!!

tipo:

public interface BlaBla {
      ...
}
public class BlaBlaSuperior {

       public static BlaBla metodo(){
       ..... 
       }
}
public class Main {

       BlaBla x = BlaBlaSuperior.metodo();  

}

pelo menos ao meu ver é isso… tipo quer dizer que a interface BlaBla passa a ser um objeto??? por que tipo é apenas um interface, e um método de um classe retorna essa interface, é isso que eu não entendi!!!
Ainda acho a resposta :lol:

Obrigado pela atenção!

Entendi(espero!)

No seu caso temos:

BlaBla x = BlaBlaSuperior.metodo();  

Não é que BlaBla passa a ser objeto, é que ele recebe a referência (ponteiro) de
um objeto que implementa BlaBla (daí a possibilidade de atribuir à variável x).

Este objeto que x recebe (referência) tem uma implementação do seu método metodo();
Então o seu x não se “transforma” em um objeto e sim recebe uma referência do objeto
criado.
Como ele agora tem a referência ao objeto instanciado (que por sua vez possui código no método metodo();),
ele pode chamar o seu método metodo(); normalmente:
x.metodo();

Clareou um pouco mais?

Abraços!

Blz amigos, vou tentar explicar de forma simples e com cuidado para não prejudicar com o entendimento do nosso amigo.
pense em uma interface Carro ok.

public interface Carro(){
            public int getVelocidadeTotal();
            public int getValor();

}

imagine agora que vc tem uma fábrica de carro e dependendo do que o cliente quizer vc vai criar os carros para ele. Suponha que sua fábrica cria dois tipos de carros.
Ferrari e Fusca ok.

//Ferrari

public class Ferrari implements Carro{

@Override
public int getVelocidadeTotal() {
    return 310;
}

@Override
public int getValor() {
    return 2000000;
}

}

//FUSCA
public class Fusca implements Carro{

@Override
public int getVelocidadeTotal() {
    return 100;
}

@Override
public int getValor() {
    return 500;
}

}

blz, só lembrando, vc tem uma fábrica e que faz dois tipod de carro, FERRARI E FUSCA

//aqui sua fabrica de carros ok

public class FabricaCarro {
static public int tipo;

public FabricaCarro(int tipoCarro) {
    tipo = tipoCarro;
}

static public Carro criarCarro(){
    Carro carroCriado = null;
    if(tipo == 1){
        carroCriado = new Fusca();
    }else{
        carroCriado = new Ferrari();
    }
    return carroCriado;
}

}

// dependendo do que o seu cliente quer vc vai retornar o carro para ele ok.

public class Testando {

public static void main(String[] args){
    
    // seu cliente quer um fusca
     Carro carro = FabricaCarro.criarCarro(1);

    System.out.println(carro.getValor());


   // seu cliente quer uma ferrari
     Carro carro = FabricaCarro.criarCarro(2);

    System.out.println(carro.getValor());

}

}

bom acho que isto resolve o problema. Com isto vc pode criar fabricas de conexões, como o caso do connection e sempre que vc quiser instanciar objetos dependendo do atributo, vc pode abstrair algumas coisas e criar fabricas para aquilo que vc queira.

cara foi mal pela tags de formatação de código. Fora isto acho que dar para entender ok.

ha desculpando ai, como fiz rápido e só depois parei para ver o código. corrigindo a classe FabricaCarro pode ficar assim:

<code>
public class FabricaCarro {

static public Carro criarCarro(int tipoCarro){
    Carro carroCriado = null;
    if(tipoCarro == 1){
        carroCriado = new Fusca();
    }else{
        carroCriado = new Ferrari();
    }
    return carroCriado;
}

}
</code>

Experimente imprimir a classe do objeto Statement:

Statement x = conn.createStatement(); System.out.println(x.getClass().getCanonicalName());

Você vai ver que a classe é algo como:
com.mysql.Statement

E isso não é a interface, e sim, uma classe concreta, que implementa a interface Statement. O mesmo vale para a connection.

O que está acontecendo, então, é o seguinte:
Você pede uma connection para o DriverManager.

Este, procura por uma classe concreta nos drivers, até achar. Se você tiver no MySQL, provavelmente ele te retornará uma com.mysql.Connection.
A partir daí, essa classe concreta irá retornar para você Statements e ResultSets também concretos.

No fundo, é mais ou menos como fazer:

List<String> lista = new ArrayList<String>();

Mas disfarçado assim:

public List<String> criarLista() { return new ArrayList<String>(); }

Note que quem usa o método, só vê isso aqui:

List<String> x = criarLista();

E não tem noção de que classe concreta o método criarLista() está retornando.

Pera ae… deixa eu ver se eu entendi!!!

Então que dizer que o DriverManager.getConnection("…"); é como se ele utiliza a interface Connection dentro do método e escreve todo o corpo dos métodos necessario, que dái seria mesma coisa que fazer :

Connection con = new Connection() {
...
};

Mais no caso o DriverManager jah faz isso pra vc???
É isso??? ou errei???
:lol: :lol:

Acho que agora eu reparei que não é isso, por que, o que eu saiba, não tem como criar um método dentro de um método!!!
:oops:

Mais ou menos.

É como se ele fizesse assim:

[code]public Connection getConnection(string connstr) {
if (temInstalado(“mysql”))
return new MySqlConnection(connstr);
if (temInstalado(“postgre”)
return new PostgreConnection(connstr);
if (temInstalado(“sqlserver”)
return new SqlServerConnection(connstr);
if (temInstalado(“oracle”))
return new OracleConnection(connstr);

throw new SqlException("Could not find driver for: " + connstr);
}[/code]

Só que claro, ele faz isso de uma maneira um pouco mais inteligente, sem precisar de tantos ifs.

[quote=ViniGodoy]Mais ou menos.

É como se ele fizesse assim:

[code]public Connection getConnection(string connstr) {
if (temInstalado(“mysql”))
return new MySqlConnection(connstr);
if (temInstalado(“postgre”)
return new PostgreConnection(connstr);
if (temInstalado(“sqlserver”)
return new SqlServerConnection(connstr);
if (temInstalado(“oracle”))
return new OracleConnection(connstr);

throw new SqlException("Could not find driver for: " + connstr);
}[/code]

Só que claro, ele faz isso de uma maneira um pouco mais inteligente, sem precisar de tantos ifs.[/quote]

e isso funciona mais ou menos o mesmo para Statement e ResultSet, a partir do momento que o Connection sabe com qual banco de dado vai trabalhar??

Acho que o que ta te impedindo de entender pode ter haver com isto:


Cachorro dog = new Cachorro();

Antes do sinal de igual (Cachorro dog) nos temos uma declaração, alí ainda não tem nenhum objeto concreto, você só está informando um nome de um ponteiro, ou seja, analogamente vamos dizer que você criou um “controle remoto” que tem capacidade de controlar objetos concretos do tipo Cachorro. ( controle remoto de cachorro)

Do lado direito do sinal de igual é onde realmente está sendo construido algo de concreto (new Cachorro()), o objeto Cachorro é criado junto do operador new, tenha em mente que é neste pedaço que o verdadeiro objeto nasce.

Neste ponto, nos temos duas coisas separadas, temos um controle remoto que tem a capacidade de controlar Cachorro, e temos um objeto Cachorro criado segundo nossa requisição (new Cachorro), a atribuição(sinal de igual) faz com que o controle remoto(dog) aponte para o objeto cachorro, ou seja, dog não é o cachorro, ele é um ponteiro(“controle remoto”) que tem a capacidade de controlar o cachorro.

Agora a parte polimorfica

Digamos que Cachorro implemente a interface Animal

public class Cachorro implements Animal{

E esta interface(Animal) tem o metodo correr();

Tendo isto em mente eu faço a seguinte decaração:

Animal dog = new Cachorro();

Como pode isso sendo que Animal é uma interface???

Como no exemplo anterior, dog é só um controle remoto que controla Animal, ou seja, ele pode receber um Cachorro, pois o cachorro implementa(é do tipo) Animal(o cachorro tem o método correr() obrigatoriamente).

A parte interessante, é que se Cachorro tiver outros metodos como Latir(), que a interface Animal não possui, este controle remoto(dog) não terá acesso a estas peculiaridades, pois você criou um controle remoto que tem botoes so para controlar metodos de Animal e nao de um cachorro em especifico, no caso do exemplo, o cachorro so ia conseguir correr() e não latir(). A não ser que você executasse uma conversao de tipo (Cast), mas isto é outra historia.

Acho que essa explicação é o máximo que consigo rs

De qualquer forma, espero ter te ajudado.