2013-04-21 4 views
2

Я ищу хороший способ иметь разные реализации того же метода, который определен в интерфейсе, но с разными типами параметров. Возможно ли это?Реализация методов из интерфейса, но с различными параметрами

Чтобы уточнить это, предположим, что у меня есть база данных интерфейса и два класса реализации Database1 и Database2. У базы данных есть метод createNode (...) и еще один editNode (...). Проблема в том, что для Database1 возвращаемый тип метода createNode должен быть длинным (идентификатором). Однако для Database2 это будет объект, специфичный для этой технологии (в данном случае OrientDB, но это не имеет большого значения, это просто то, что расширяет Object, конечно). А также оба типа (...) возвращаемых типов должны использоваться как один из параметров editNode (...).

То, что я думал сделать, это:

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

Я хотел бы знать, если есть лучший способ сделать это. Специально избегать Long -> long and long -> Long conversion. Я видел много подобных вопросов здесь, в StackOverflow, но ни один из них не был тем, что я искал. Заранее большое спасибо.

+0

* Различные реализации того же метода, которые определены в интерфейсе, но с разными типами параметров * Нет – NINCOMPOOP

+0

Вам нужны дженерики. – SLaks

ответ

5

Вот пример Дженерики

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, не беспокойтесь о autoboxing. Вы используете JDK> = 5, поскольку есть аннотации @Override.

+0

Это было действительно полезно, я действительно беспокоился о автобоксинге из-за производной потери производительности. –

+0

Затем, в этом примере, как мне позвонить из основного метода в основном классе, сначала создайтеNode (...), а затем, с выходом createNode (...), изменитеNode (SomeObject createNodeOutput, .. .), если типы динамические? –

+0

В случае 'Database1' вы создадите экземпляр' SomeObject' просто путем вызова 'createNode' в своем экземпляре.В случае «Database2» вам придется создать экземпляр «SomeObject» самостоятельно, но, пожалуйста, избегайте [raw types] (http://docs.oracle.com/javase/tutorial/java/generics/methods.html). – lifus

2

Я думаю, вы хотите Generic Methods.

Общие методы - это методы, которые вводят свои собственные параметры типа. Это похоже на объявление общего типа, но область применения параметра ограничена способом, в котором она объявлена. Static и допускаются нестатические общие методы, а также стандартные классы .

Синтаксис для общего метода включает параметр типа внутри угловых скобок и появляется перед возвращаемым типом метода. Для статических общих методов раздел параметров типа должен появиться перед возвращаемым типом метода.