Создание экземпляра защищенного класса из внешнего пакета

#java #oop #generics

#java #ооп #общие сведения

Вопрос:

Я переписал код бинарного дерева поиска, найденный в следующих ссылках, для работы в общем виде — класс будет работать с любым параметром типа. http://www.informatics.susx.ac.uk/courses/dats/DataStructures/SearchTree.java http://www.informatics.susx.ac.uk/courses/dats/teach/code/demos/SearchTreeDemo.java

Я поместил свой общий SearchTree.java в пакете с именем mysearchtree и импортировал его в SearchTreeDemo.java .

SearchTree.java содержит: Абстрактный класс SearchTree. Конкретный класс EmptyTree, который имеет защищенный конструктор. Конкретный класс NodeTree, который также имеет защищенный конструктор.

Исходное, не являющееся универсальным кодирование для абстрактного класса SearchTree заключалось в том, что клиент кода создавал экземпляр объекта EmptyTree с помощью статического метода, как показано ниже:

 public abstract class SearchTree {
    /**
     * Returns an empty tree.
     */
    public static SearchTree empty() {
        return new EmptyTree();
    }

    // more code
}
 

Это было бы использовано следующим образом:

 SearchTree t = SearchTree.empty();
t = t.add( new String("hello") );
 

При работе с дженериками я переписал класс, чтобы иметь следующую структуру:

 public abstract class SearchTree<T extends Comparable<T>> {
    public abstract boolean isEmpty();
    public abstract int numNodes();
    public abstract boolean contains(T key);
    public abstract SearchTree<T> add(T item);
    public abstract SearchTree<T> remove(T item);
    public abstract String toString();
}
 

Первоначальный план предоставления статического метода, который возвращал бы EmptyTree, не будет работать в общем случае (вы не можете использовать параметры универсального типа класса в статическом методе).

Мой вопрос: как мне предоставить типобезопасный способ, позволяющий клиенту этого кода создавать экземпляр EmptyTree извне пакета (или какой-либо другой эквивалентный механизм, который заменил SearchTree t = SearchTree.empty() бы код)?

Обновить:

Я пробовал следующее, но получаю сообщение об ошибке:

 public static <U> SearchTree<U> createSearchTree() { return new EmptyTree<U>(); }
 

Ошибки:

 ./mysearchtree/SearchTree.java:7: type parameter U is not within its bound
    public static <U> SearchTree<U> createSearchTree() { return new EmptyTree<U>(); }
                                 ^
./mysearchtree/SearchTree.java:7: type parameter U is not within its bound
    public static <U> SearchTree<U> createSearchTree() { return new EmptyTree<U>(); }
                                                                              ^
2 errors
 

Ответ №1:

Является ли что-то подобное тем, что вы ищете? Параметризованный метод.

 public static <Y extends Comparable<Y>> SearchTree<Y> empty() {
   return new SearchTree<Y>();
} 
 

Комментарии:

1. Это идеально — я попробовал это, но забыл указать Y предел extends Comparable<Y> . Спасибо!

Ответ №2:

Если конструкторы защищены, единственный способ, который я могу придумать, — это либо одноэлементные, либо фабричные шаблоны (последнее гораздо более логично).

Комментарии:

1. Спасибо за ответ. Я только начал изучать шаблоны проектирования. Не могли бы вы вкратце объяснить, как здесь можно применить фабричный шаблон? Спасибо.

Ответ №3:

Может быть, передать класс в ваш метод staic?