Об ошибке с использованием обобщений Java: «параметр типа S находится за его пределами» - PullRequest
9 голосов
/ 12 декабря 2010

Я пишу некоторые классы, используя Generics, но не могу найти решение для класса SolutionsSubset и поэтому я получаю ошибку msgstr "параметр типа S находится за его пределами". Я прочитал предыдущий вопросы о той же ошибке, но я не могу решить ее для моего случая. Может ли кто-нибудь помочь мне улучшить мои знания о дженериках? любой Ссылка на хорошую книгу (я могу найти в Google много информации но если кто-то может рекомендовать книгу, учебник и т. д. будет приветствоваться). Хотя я пытался запомнить правила, чтобы задать вопрос, но я извиняюсь, если мой вопрос не соответствует этим правилам.

У меня есть следующие классы и интерфейсы:



public interface Subset<T extends Comparable<T>> extends Comparable<Subset<T>>
public class MathSubset<T extends Comparable<T>> extends TreeSet<T> implements Subset<T>

public interface Solution<T extends Comparable<T>>

public interface Solutions<S extends Solution<?>> extends Iterable<S>
public class SolutionsSubset<S extends Solution<?>> extends MathSubset<S> implements Solutions<S>


Мне нужно, чтобы Подмножество расширяло Comparable. В SolutionsSubset класс MathSubset хранит объекты Solution. Как мне изменить это определение, чтобы оно работало?

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

Ответы [ 3 ]

7 голосов
/ 13 декабря 2010

Для использования в качестве аргумента типа в MathSubset, SolutionsSubset s S должен extend Comparable<S>.В качестве компилируемого примера:

import java.util.TreeSet;

interface Subset<T extends Comparable<T>>
     extends Comparable<Subset<T>> { }

class MathSubset<T extends Comparable<T>>
    extends TreeSet<T>
    implements Subset<T>
{
    public int compareTo(Subset<T> other) { throw new Error(); }
}

interface Solution<T extends Comparable<T>> { }

interface Solutions<S extends Solution<?>> extends Iterable<S> { }

class SolutionsSubset<S extends Solution<?> & Comparable<S>>
    extends MathSubset<S>
    implements Solutions<S>
{ }

Несколько комментариев: Это очень абстрактный пример, и о нем нелегко думать.Выкладывать код, чтобы вам не нужно было прокручивать, это хорошо.Здесь происходит очень много наследства, возможно, сочинения, а не, скажем, расширения TreeSet.Трудно провести различие между идентификаторами Solutions и Solution.

2 голосов
/ 12 декабря 2010

Дженерики - это то, что может быстро выйти из-под контроля, особенно если вы попытаетесь «быть универсальными» сразу. Меньше - больше. Что всегда помогает мне, так это начинать с конкретного (включая реализацию), а затем медленно заменять общие параметры по одному параметру и классу за раз.

Может ли кто-нибудь помочь мне улучшить мои знания о дженериках?

http://www.angelikalanger.com/GenericsFAQ/JavaGenericsFAQ.html

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

1 голос
/ 12 декабря 2010

Прежде всего, вот полная ошибка (которая связана с тем, что MathSubset не получает правильный параметр): Bound mismatch: The type S is not a valid substitute for the bounded parameter <T extends Comparable<T>> of the type QifFixer.MathSubset<T>

Проблема в том, что MathSubset ожидает <T extends Comparable<T>, но вы даетеэто S extends Solution<?> - те типы, которые не имеют ничего общего друг с другом, потому что решение не наследует или не реализует Comparable<T>.

Если что, вы можете попробовать это:

public class SolutionsSubset<S extends Comparable<S>> extends
    MathSubset<S> implements Solutions<Solution<S>>;

К сожалению, это ВСЕ ЕЩЕ не сработает, потому что MathSubset реализует Iterable, но тоже делает Решения.

Было бы легко исправить, чтобы Решения не расширяли Iterable, но для меня действительно звучит так, будто вы пытаетесь использоватьболее сложный подход, чем нужно.Может быть, «has-a» вместо «is-a» может быть более полезным здесь?

...