预定义接口的抽象方法如Connection,Statement等如何在没有主体的情况下执行某些任务?
在Java中有许多预定义的接口,如ResultSet
, Connection
, Statement
等。接口只能有抽象方法(未实现的方法)。所以我们为什么要使用那些方法而不先定义它们。
例如,在以下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();}}
这里是我们调用Connection
和Statement
接口的抽象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
类及其包提供缺少的部分,返回具有完整方法体的具体类。 但是,您只能通过接口与客户端代码端的这些类进行交互。 具体类的实现细节有效地隐藏在视图之外。