预定义接口的抽象方法如Connection,Statement等如何在没有主体的情况下执行某些任务?

在Java中有许多预定义的接口,如ResultSetConnectionStatement等。接口只能有抽象方法(未实现的方法)。所以我们为什么要使用那些方法而不先定义它们。

例如,在以下jdbc代码中

 public class JDBCSample { public static void main( String args[]) { String connectionURL = "jdbc:postgresql://localhost:5432/movies; user=java;password=samples";` try { Class.forName("org.postgresql.Driver"); Connection con = DriverManager.getConnection (connectionURL); Statement stmt = con.createStatement(); ResultSet rs = stmd.executeQuery("select moviename, releasedate from movies"); while (rs.next()) {....do something.....} }catch (SQLException e) {e.printStackTrace();} catch (Exception e) { e.printStackTrace();}} 

这里是我们调用ConnectionStatement接口的抽象createStatement()executeQuery()方法吗? 如果是,那么抽象方法(没有身体的方法)如何执行某项任务?

当您调用DriverManager.getConnection ,它将返回org.postgresql.jdbc4.Jdbc4Connection的实例,该实例是一个实现java.sql.Connection接口的类。

Jdbc4Connection有一个createStatement的方法体,它返回一个org.postgresql.jdbc4.Jdbc4Statement实例,它是一个实现java.sql.Statement接口的类。

Jdbc4Statement有一个executeQuery方法体,它返回一个org.postgresql.jdbc4.Jdbc4ResultSet实例,它是一个实现java.sql.ResultSet接口的类。

呼叫:

 System.out.println(con.getClass()); 

并注意到实际对象不是Connection类型。 这称为多态性 。 简单地说, DriverManager.getConnection()返回一些实现Connection 东西 。 你正在调用那些东西的方法。 这是多态的一个优点 – JDBC驱动程序以后可以决定更改某些内容 ,只要它实现了Connection ,您的代码就不会那么在意。

直截了当的例子:

 List list = new ArrayList(); list.size(); //calling abstract method?!? No! 

在上面的例子中,我们实际上是在调用ArrayList.size()

您正在调用实现此方法的类的方法。

DriverManager.getConnection返回Connection接口的具体实现,您不需要知道返回的确切类。 这是接口的主要思想。

当你实际调用某个东西时,你所拥有的引用是一个提供所有实体的具体子类的实例。 关键是你(作为客户端)不需要关心那个实现是什么 – 它是由DriverManager (etc)为你提供的。 所有你需要关心的是它是“实现给定接口的东西”或“扩展抽象类的东西”。

一个更简单的例子是使用集合类型:

 List list = new ArrayList(); doSomething(list); ... public static void doSomething(List list) { // Act on the list } 

在这里, doSomething不需要知道我们使用了ArrayList – 它可以在任何类型的List ……但正如你所看到的,我们创建了一个ArrayList的实例,这是一个具体的课程。

您正在使用的接口的特定实现(在本例中为DriverManager )返回一个实现接口抽象方法的具体类。

正如您所指出的,接口仅声明具体实现必须提供的方法。 实际的实现类提供了这些方法的主体。

DriverManager类及其包提供缺少的部分,返回具有完整方法体的具体类。 但是,您只能通过接口与客户端代码端的这些类进行交互。 具体类的实现细节有效地隐藏在视图之外。