Мне очень нравится использовать инициализаторы, чтобы сделать сборку и настройку классов более понятными. В основном я предпочитаю это:Ядро, возвращающее Java подкласс без общего параметра в методе суперкласса
new ClassObj().StartingFrom(1).EndingAt(5).IncrementBy(1).Backwards();
Вместо этого:
new ClassObj(1,5,1,false);
Это немного боль в Java при смешивании с наследованием, как возвращение типов по умолчанию как родовое, насколько это возможно. Я нашел работоспособное решение с использованием самореференциального наследования (Java: returning subclass in superclass method signature), но у меня возникли проблемы с ним.
Моя проблема в том, что класс родителя реализует Iterable, но параметр родового типа теряется, поэтому цикл for-each хочет вернуть объект вместо файла.
Вот SSCCE показывает поведение:
public class SSCCE {
private static abstract class Sentence<T extends Sentence<T>> implements Iterable<String> {
protected LinkedList<String> Words = new LinkedList<>();
abstract T self();
public T Say(String word) {
Words.add(word);
return self();
}
@Override
public Iterator<String> iterator() {
return Words.iterator();
}
}
static class QuietSentence extends Sentence<QuietSentence> {
public QuietSentence Whisper(String word) {
Say(word.toLowerCase());
return this;
}
@Override
QuietSentence self() {
return this;
}
}
static class LoudSentence extends Sentence<LoudSentence> {
public LoudSentence Shout(String word) {
return Say(word.toUpperCase());
}
@Override
LoudSentence self() {
return this;
}
}
static void PrintWords(Sentence words) {
for(Object obj : words) {
// I'd really like to avoid this cast
String word = (String)obj;
System.out.println(new StringBuilder(word).append(": ").append(word.length())
.toString());
}
}
public static void main (String[] args) {
QuietSentence peaceful_words = new QuietSentence().Say("Hello").Whisper("World");
PrintWords(peaceful_words);
LoudSentence noisy_words = new LoudSentence().Say("Hello").Shout("World");
PrintWords(noisy_words);
}
}
Что происходит, и как я могу это исправить?
Вы знаете, что '(T) это небезопасный литье, не так ли? – newacct
Обычно это было бы. В этом случае 'T', как известно, является либо типом' Sentence', либо одним из его подклассов, поэтому безопасно делать трансляцию. – Morgen
Nope. Это небезопасно. да, 'T', как известно, является подтипом' Sentence ', но' Sentence ', как известно, не является подтипом' T'. –
newacct