4

I am looking for a good way to have different implementations of the same method which is defined in an interface but with different parameter types. Would this be possible?

In order to clarify this, suppose I have an interface Database and two implementing classes Database1 and Database2. Database has a method createNode(...) and another one modifyNode(...). The problem is that for Database1 the return type of the createNode method should be a long (the identifier). For Database2, however, it would be an object specific from the technology (in this case OrientDB but this doesn't matter too much, it is simply something that extends Object, of course). And also both create(...) return types should be used as one of modifyNode(...) parameters.

What I was thinking to do is:

`public interface Database {
    public Object createNode(...);
    public void modifyNode(Object id, ...);
    ...
 }`

public class Database1 { 
    @Override
    public Object createNode(...) { 
        ...
        long result = // obtain id of created node
        return Long.valueOf(result);
    }

    @Override
    public void modifyNode(Object id, ...) { 
        ...
        // use id as ((Long)id).longValue();
    }
}

public class Database2 { 
    @Override
    public Object createNode(...) { 
        ...
        SomeObject result = // obtain id of created node
        return result;
    }

    @Override
    public void modifyNode(Object id, ...) { 
        ...
        // use id as (SomeObject)id
    }
}

I wanted to know if there is a better way to do this. Specially to avoid Long -> long and long -> Long conversions. I saw many similar questions here in StackOverflow but none of them were what I was looking for. Thank you very much in advance.

Lucia Pasarin
  • 2,268
  • 1
  • 21
  • 37
  • *different implementations of the same method which is defined in an interface but with different parameter types* No – AllTooSir Apr 21 '13 at 13:06

2 Answers2

6

Here's an example of Generics

Database

public interface Database<T> {
    public T createNode(...);
    public void modifyNode(T id, ...);
    ...  
}

Database1

class Database1 implements Database<Long> { 
    @Override
    public Long createNode(...) { 
        ...
        long result = // obtain id of created node
        return result;
    }

    @Override
    public void modifyNode(Long id, ...) { 
        ...
        // use id
    }
}

Database2

public class Database2 implements Database<SomeObject> { 
    @Override
    public SomeObject createNode(...) { 
        ...
        SomeObject result = // obtain id of created node
        return result;
    }

    @Override
    public void modifyNode(SomeObject id, ...) { 
        ...
        // use id as (SomeObject)id
    } 
}

Btw, don't worry about autoboxing. You are using JDK >= 5 since there are @Override annotations.

lifus
  • 8,074
  • 1
  • 19
  • 24
  • This was really useful, I was actually worrying about autoboxing because of the derived performance loss. – Lucia Pasarin Apr 21 '13 at 13:48
  • Then, in this example, how should I call, from a main method in a Main class, first createNode(...), and then, with the createNode(...) output, the modifyNode(SomeObject createNodeOutput, ...), if the types are dynamic? – Lucia Pasarin Apr 21 '13 at 16:20
  • In case of `Database1` you will create an instance of `SomeObject` simply by calling `createNode` on its instance. In case of `Database2` you will have to create an instance of `SomeObject` on your own, but please avoid [raw types](http://docs.oracle.com/javase/tutorial/java/generics/methods.html). – lifus Apr 21 '13 at 18:37
  • I mean a way to call both methods through Database, not by using Database1 and Database2 separately. And from an external class (Main class, for example). – Lucia Pasarin Apr 21 '13 at 22:08
  • Please Don't use raw type `Database`, use either `Database` or `Database1` to declare instances of class `Database1`. Write a code to handle both `Database1` and `Database2`. I also suggest you to write generic method in `Main` class. [See link provided by Achintya Jha.](http://docs.oracle.com/javase/tutorial/java/generics/methods.html) – lifus Apr 22 '13 at 07:35
  • By _Write a code to handle both Database1 and Database2_ I mean that you may create `Database1Handler` and `Database2Handler` and move common code in some `AbstractDatabaseHandler`. Generally, It's not a very good idea to make your main class to be expert in everything. – lifus Apr 22 '13 at 07:56
2

I think you want Generic Methods.

Generic methods are methods that introduce their own type parameters. This is similar to declaring a generic type, but the type parameter's scope is limited to the method where it is declared. Static and non-static generic methods are allowed, as well as generic class constructors.

The syntax for a generic method includes a type parameter, inside angle brackets, and appears before the method's return type. For static generic methods, the type parameter section must appear before the method's return type.

Achintya Jha
  • 12,735
  • 2
  • 27
  • 39