Call implemented interface overriden method from a class

I'm starting to do a bit of advanced things in Java (For me are advanced xD).

I had this:

interface ResultSet {
    public void close();
}

class DbResult {
    ResultSet data;
    Statement statement;

    public void close() {
        this.data.close();
        this.statement.close();
    }
}

I've tried to do this:

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();
    }
}

Obviously it don't works because ResultSet is not a superclass. I also tried to make DbResult an interface and extending ResultSet but it tells me that interface methods cannot have a body, so I don't know how to do this.

I'm trying to do this so I can close the result statement and result having only one variable instead of 2, so is less prone to memory leaks for forgetting closing the statement.

The Database class queries the database this way:

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;
    }

EDIT: Ok, now that I know that I can't I want to know if I can do this in a hackish form I though:

Is there a way of checking if a method that does not exists is called in a class, catch it and invoke that method name in another variable?

For example, ResultSet has a method called getString(). I want to know if is possible to call DbResult.getString("blah"); and DbResult will redirect that method to this.data but withou implementing the getString method inside the DbResult class.

I would like to know if is possible because there are tons of functions in the ResultSet and calling DbResult.data.METHOD is less elegant than DbResult.METHOD.

Answers


Is there a way of checking if a method that does not exists is called in a class, catch it and invoke that method name in another variable?

So you want to wrap calls to an instance without having to extend it or implementing each of its methods, that's actually possible, but only for methods exposed over interfaces. Good news is that ResultSet is in fact an interface.

This can be done by means of dynamic proxies (see Proxy and InvocationHandler).

You can create a Proxy backed by an InvocationHandler which wraps the ResultSet. Any calls to your proxy instance will be delegated to the InvocationHandler, which can process them directly or, in your case, delegate them to the wrapped actual ResultSet instance.

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);
    }
}

Usage:

// the actual result set
ResultSet resultSet = ...

// and your wrapped proxy/handler as a surrogate
resultSet = MyResultSetInvocationHandler.wrap(resultSet);

Perhaps what you want to use is an abstract class and not an interface, something like:

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();  
   }
}

and to test it

public class TestA {
   public static void main(String[] args) {
      A2 myA = new B2();
      myA.foo();
   }
}

Edit Regarding the changes in your question, which changes everything and drastically, I'm confused (again). Is ResultSet your interface, or are you trying to implement the java.sql.ResultSet? If the latter, your code will be fraught with difficulty since your class cannot extend and cannot substitute for the actual type of ResultSet returned by the query. I don't see any substitute for your using composition and not inheritance. In other words, go with what you were originally doing -- creating classes that contain ResultSet fields but not one that implements the interface.

Note that you can implement ResultSet if you use the Decorator Pattern. With this you would create your own class that is a "wrapper" for the original type, and it will require you to use composition and inheritance, and to create all the needed methods for the interface and then delegate them to the ResultSet component.

For example, ResultSet has a method called getString(). I want to know if is possible to call DbResult.getString("blah"); and DbResult will redirect that method to this.data but withou implementing the getString method inside the DbResult class.

No, you would have to have all these methods implemented in your child decorator class.


Guess what: it's already part of Java (since version 7):

Java API Documentation: java.lang.AutoCloseable

public interface AutoCloseable {
   void close();
}

ResultSet, Statement (and many other classes) already implement this interface. And the best thing: resources managed by the try in a try-statement are automatically closed, if they implement this interface.


Need Your Help

Add ambient light sensor into cordova-2.5.0.js - phonegap

android cordova phonegap-plugins

I have to develop an Android application using phongap that retrives the sensors data from the device.

extract info out of XML tag - RUBY

ruby xml

I have an xml tag like this

About UNIX Resources Network

Original, collect and organize Developers related documents, information and materials, contains jQuery, Html, CSS, MySQL, .NET, ASP.NET, SQL, objective-c, iPhone, Ruby on Rails, C, SQL Server, Ruby, Arrays, Regex, ASP.NET MVC, WPF, XML, Ajax, DataBase, and so on.