Как избежать предупреждения типа параметра для самоссылающихся типов безопасного интерфейса в Java? - PullRequest
0 голосов
/ 03 августа 2010

Я работаю с деревом в Java, и у меня есть следующий интерфейс для простого неупорядоченного дерева с собственной ссылкой:

public interface Node<N extends Node> {

  public N getParent();
  public void setParent(N parent);

  public Collection<N> getChildren();

  public void addChild(N node);
  public void removeChild(N node);

  public N getRootNode();

  ... more ...
}

Идея, конечно же, заключается в создании типобезопасного узла

  public abstract class ParentChildNode<E extends Node> implements Node<E> {

проблема, которая меня действительно раздражает, это предупреждение, которое я получаю:

ParentChild is a raw type. References to generic type Node<N> should be parameterized

warning on this line:

public interface Node<N extends Node> {

warning on this line:

    public abstract class ParentChildNode<E extends ParentChild> implements ParentChild<E>  

Я могу сделать:

public interface Node<N extends Node<?>> {

но я боюсь, что я наступаю на территорию yuckness . Я могу подавить предупреждение, но это не разрешено, где я работаю.

есть предложения? Я заметил, что API-интерфейс коллекций java.util нигде не предупреждает.

заранее спасибо

Ответы [ 2 ]

3 голосов
/ 03 августа 2010

как насчет этого (параллельно объявлению класса Enum):

public interface Node<N extends Node<N>> {

  public N getParent();
  public void setParent(N parent);

  public Collection<N> getChildren();

  public void addChild(N node);
  public void removeChild(N node);

  public N getRootNode();

  ... more ...
}

public abstract class ParentChildNode implements Node<ParentChildNode> {
1 голос
/ 03 августа 2010

Ваш тип бесконечно рекурсивен. Все ваши узлы действительно имеют тип Node<Node<Node<Node<…>>>> или какой-то одинаково бесконечный подтип. Обобщения Java просто недостаточно мощны, чтобы справляться с такими вещами.

Более того, если у вас есть дерево этих узлов, какой тип корня? У него нет родителя. Я полагаю, вы могли бы иметь тип NullNode<GodKnowsWhat>, но это просто откладывает проблему. Я полагаю, что корень может просто вернуть null в качестве родителя, но это разрушает всю иерархию.

Что вы могли бы иметь вместо этого: Я получил это далеко:

public interface Node {
    public Collection<ChildNode<Node>> getChildren();

    public void addChild(ChildNode<Node> node);
    public void removeChild(ChildNode<Node> node);
}

public interface ChildNode<Parent> extends Node {
    public Parent getParent();
    public void setParent(Parent parent);
}

Но тип методов Node неправильный. Вы просто не можете сделать это на Java. Если вы действительно хотите, попробуйте Scala. Он работает на JVM, и его система типов намного сложнее; Я совершенно уверен, что это позволит вам использовать рекурсию типа. Кроме того, вы можете быть в состоянии осуществить это в C ++. C ++ также имеет гораздо более мощную систему типов, но я недостаточно поработал с ней, чтобы понять, позволит ли она вам делать подобные вещи в более или менее таких терминах.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...