![](/img/trans.png)
[英]How do I change the signature of a method I have overriden from my interface that I implemented onto the concrete class I'm using?
[英]Call implemented interface overriden method from a class
我開始用Java做一些高級的東西(對我來說是先進的xD)。
我有這個:
interface ResultSet {
public void close();
}
class DbResult {
ResultSet data;
Statement statement;
public void close() {
this.data.close();
this.statement.close();
}
}
我試過這樣做:
interface ResultSet { //I think that is abstract or something
public void close();
}
abstract class DbResult implements ResultSet {
Statement statement;
@Override
public void close() {
super.close();
this.statement.close();
}
}
顯然它不起作用,因為ResultSet不是超類。 我還試圖讓DbResult成為一個接口並擴展ResultSet,但它告訴我接口方法不能有一個主體,所以我不知道如何做到這一點。
我正在嘗試這樣做,所以我可以關閉結果語句,結果只有一個變量而不是2,所以不會因忘記關閉語句而導致內存泄漏。
Database類以這種方式查詢數據庫:
class Database {
private Connection connection;
/* Here a constructor that
inits the connection and such things */
public DbResult query(String q) {
Statement statement = this.connection.createStatement();
DbResult result = (DbResult)statement.executeQuery(q);
result.statement = statement;
return result;
}
編輯:好的,現在我知道我不能想知道我是否可以用hackish形式做到這一點我:
有沒有辦法檢查是否在類中調用了不存在的方法,捕獲它並在另一個變量中調用該方法名稱?
例如, ResultSet
有一個名為getString()
的方法。 我想知道是否可以調用DbResult.getString("blah");
並且DbResult
會將該方法重定向到this.data
但是在DbResult類中實現getString
方法。
我想知道是否可行,因為ResultSet
有大量函數,並且調用DbResult.data.METHOD
不如DbResult.METHOD
優雅。
也許您想要使用的是抽象類而不是接口,例如:
interface A2 {
void foo();
void otherAbstractMethod();
}
abstract class AbstractA2 implements A2 {
@Override // implemented metthod
public void foo() {
System.out.println("From the default method");
}
@Override //unimplemented abstract method
public abstract void otherAbstractMethod();
}
class B2 extends AbstractA2 {
@Override
public void foo() {
super.foo();
System.out.println("From the override");
}
@Override
public void otherAbstractMethod() {
// TODO add some code
// the line below won't compile
// super.otherAbstractMethod();
}
}
並測試它
public class TestA {
public static void main(String[] args) {
A2 myA = new B2();
myA.foo();
}
}
編輯
關於你的問題的變化,這些變化會徹底改變一切 ,我很困惑(再次)。 ResultSet是您的界面,還是您正在嘗試實現java.sql.ResultSet? 如果是后者,您的代碼將充滿困難,因為您的類無法擴展,並且無法替代查詢返回的ResultSet的實際類型。 我沒有看到任何替代你的使用組合而不是繼承。 換句話說,繼續你最初做的事情 - 創建包含ResultSet字段的類,但不創建實現接口的字段。
請注意,如果使用裝飾器模式,則可以實現ResultSet。 有了這個,您將創建自己的類,它是原始類型的“包裝器”, 它將要求您使用組合和繼承,並為接口創建所有需要的方法,然后將它們委托給ResultSet組件。
例如,ResultSet有一個名為getString()的方法。 我想知道是否可以調用DbResult.getString(“blah”); 並且DbResult會將該方法重定向到this.data,但是在DbResult類中實現getString方法。
不,你必須在你的子裝飾器類中實現所有這些方法。
猜猜看:它已經是Java的一部分 (從版本7開始):
Java API文檔:java.lang.AutoCloseable
public interface AutoCloseable {
void close();
}
ResultSet
, Statement
(以及許多其他類)已經實現了此接口。 最重要的事:被管理的資源try
在一個try語句被自動關閉,如果他們實現了這個接口 。
有沒有辦法檢查是否在類中調用了不存在的方法,捕獲它並在另一個變量中調用該方法名稱?
因此,您希望將調用包裝到實例而不必擴展它或實現其每個方法,這實際上是可能的,但僅適用於通過接口公開的方法。 好消息是ResultSet
實際上是一個接口。
這可以通過動態代理來完成(請參閱Proxy
和InvocationHandler
)。
您可以創建由InvocationHandler
支持的Proxy
,該InvocationHandler
包裝ResultSet
。 對代理實例的任何調用都將委托給InvocationHandler
,它可以直接處理它們,或者在您的情況下,將它們委托給包裝的實際ResultSet
實例。
public class MyResultSetInvocationHandler implements InvocationHandler {
private final ResultSet wrappedResultSet;
private MyResultSetInvocationHandler(ResultSet resultSet) {
wrappedResultSet = resultSet;
}
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
try {
// call method on delegate
Object result = method.invoke(wrappedResultSet, args);
// optionally do something with the result, and return it afterwards
return result;
}
catch (Throwable ex) {
// handle exception, or rethrow it
throw ex;
}
}
/**
* Factory method, creates a dynamic proxy wrapping the given result set.
*/
public static ResultSet wrap(ResultSet delegate) {
MyResultSetInvocationHandler handler = new MyResultSetInvocationHandler(delegate);
return (ResultSet) Proxy.newProxyInstance(Thread.currentThread().getContextClassLoader(), new Class<?>[] { ResultSet.class }, handler);
}
}
用法:
// the actual result set
ResultSet resultSet = ...
// and your wrapped proxy/handler as a surrogate
resultSet = MyResultSetInvocationHandler.wrap(resultSet);
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.