2016-01-19 2 views
0

В настоящее время у меня есть абстрактный класс Network и интерфейс Node. Я хочу использовать generics, чтобы показать, какие узлы могут принимать сеть, и к каким сетям может подключаться узел. Мой текущий код выглядит следующим образом:Сопряжение общих классов в java - как лучше всего выполнить?

public abstract class Network<T extends Node> { 
    List<T> nodes; 

    public void addNode(T node) { 
     nodes.add(node); 
     node.setNetwork(this); 
    } 
} 

и

public interface Node<T extends Network> { 
    void setNetwork(T net); 
} 

, а также некоторые другие методы, но проблема уже здесь: вызов setNetwork(this) снят и может вызвать ошибку, если кто-то делает сеть узлы, которые не могут подключиться к этому сетевому классу. Есть лучший способ сделать это? Или это плохая практика в первую очередь и ее следует избегать?

+0

Что делает «классная сеть»? Разве не сеть неявно определяется набором подключенных узлов? – null

+0

@null в основном это оболочка вокруг набора узлов, который позволяет им реагировать на изменения в сети, получать другие узлы и так далее. – CypherAJ

ответ

1

Это не то, для чего были созданы дженерики. Скорее всего, вы столкнетесь с самыми различными предупреждениями и ошибками, если будете использовать этот подход. Вместо этого я бы рекомендовал вам просто добавить какой-то тип-идентификатор для каждого типа сети и проверить сетевой идентификатор при подключении - поэтому, когда вы добавляете новый узел в сеть.

+0

Я не уверен, что правильно это понимаю. Можете ли вы привести пример? – CypherAJ

+0

Например (я не могу определить, какие сети вы хотите имитировать с помощью этих интерфейсов), вы можете использовать некоторые строки, такие как «TCP» или «HTTP», чтобы однозначно идентифицировать все виды сетей и вызывать ошибку, если узел который не поддерживает сети с указанным ID, хочет подключиться к определенной сети. например: 'if (! node.supports (network.getID())) throw new IllegalArgumentException (« Networktype not supported: »+ network.getID());' – Paul

+0

Думаю, я поеду с этим. Спасибо – CypherAJ

0

Ваша самая большая проблема в том, что <T extends Node> использует необработанный тип, Node.

Если вы измените декларацию Network на:

public abstract class Network<T extends Node<Network>> { 

, то вы должны быть в состоянии назвать node.setNetwork(this) без небезопасных предупреждения.

0

Вы всегда можете сделать:

public interface Network<T extends Node<Network<T>>> { 
1

Вы можете использовать основные интерфейсы для общего Network и Node:

interface Node<N extends Network<?>> { 
    void setNetwork(N net); 
} 

interface Network<N extends Node<?>> { 
    public void addNode(N node); 
} 

, а затем промежуточные интерфейсы для конкретного Network и Node:

interface TcpNode extends Node<TcpNetwork> { 
} 

interface TcpNetwork extends Network<TcpNode> { 
} 

Затем это будет скомпилировано без предупреждений о любых типах:

class TcpNetworkImpl implements TcpNetwork { 

    private List<TcpNode> nodes; 

    @Override 
    public void addNode(TcpNode node) { 
     nodes.add(node); 
     node.setNetwork(this); 
    } 
} 

class TcpNetworkNode implements TcpNode{ 

    private TcpNetwork network; 

    @Override 
    public void setNetwork(TcpNetwork net) { 
     network = net; 
    } 

} 
+0

Вы можете создавать дополнительные специализированные вариации 'Network' и' Node' независимо друг от друга по одному и тому же шаблону (добавляя промежуточные интерфейсы и соответствующие реализации) – toKrause

Смежные вопросы