2014-08-27 2 views
0

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

public class LinkedList1<E>{ 

    class Node{ 
     E data; 
     Node next; 
    } 

    Node head; 

} 

Эта версия, вероятно, лучше, но в качестве альтернативы, есть более «прямой» версия, что делает вещи, как удаление головки (голова означает первый элемент с точки зрения клиента) немного сложнее, но все еще возможно внутри экземпляр LinkedList2:

public class LinkedList2<E>{ 

    E data; 
    LinkedList2 next; 

} 

Мне интересно, есть ли способ создать LinkedList2Child extends LinkedList2 таким образом, что next поля типа LinkedList2Child, возможно с отражением?

EDIT: это не мешает мне выполнить что-либо, так как доступна версия 1 - мне просто интересно узнать об этой проблеме в целом, и это пример.

Я знаю, что вы можете «спрятать» поля в подклассах, объявив поле с тем же именем, что и поле родителя, но это не сработает, если вы хотите использовать родительские методы, которые работают в этом поле.

+0

Почему вы не хотите использовать первую версию? Все, что вы сделали, - это исключить связанный список, и теперь у вас есть только узлы, отведя управление самим списком к клиентскому коду. Это не имеет никакого смысла. Я думаю, что это проблема XY ... пожалуйста, объясните фактическую проблему, которую вы пытаетесь решить, которая не может быть решена с помощью классов Collection. –

+0

Вам не нужно отводить управление клиенту. Вы все равно можете реализовать добавление, удаление, независимо от того, что из класса. И дело не в том, что я не хочу использовать первую версию. Это, наверное, лучше. Я просто хочу знать, возможно ли продление последнего так, как я описал. – user3391564

ответ

1

Дженерики:

public class LinkedList2<E, T extends LinkedList2>{ 

    E data; 
    T next; 

} 

public class LinkedSubclass extends LinkedList2<LinkedSubclass> { 

} 

Это при условии соблюдения обычных ограничений на то, что вы можете сделать с обобщениями (например, строительство новых «следующие» значения в базовом классе потребует принятия в классе типа-дочернего или фабричные), но будет охватывать то, что вы хотите.

0

Это называется ковариации (или типов совместно вариант возврата):

public static abstract class A 
{ 
    public A get() { ... } 
} 

public static abstract class B extends A 
{ 
    @Override 
    public B get() { ... } 
} 

Метод B#get() переопределяет A#get(). Это ортогонально (т. Е. Концептуально не связано) с дженериками.

+0

Я не думал, что это связано с дженериками. Я не уверен, что я вижу, как это позволяет эффективно иметь экземпляр подкласса внутри подкласса вместо экземпляра родительского класса. Что делать, если у меня было двоичное дерево и создать подклассу двоичного дерева с самобалансировкой, который переопределяет вставку с помощью вставки, которая выполняет операции балансировки. Когда вставка рекурсивно вызывается в поддереве дерева самобалансировки, это поддерево также должно выполнять операции балансировки и, следовательно, должно быть экземпляром подкласса самобалансировки. – user3391564