Próbuję mieć abstrakcyjną klasę podstawową dla niektórych klas budowniczych, dzięki czemu mogę z łatwością ponownie użyć kodu między implementacjami Buildera. Chcę, aby moi konstruktorzy obsługiwali metodę łańcuchową, dlatego metoda musi zwracać "tę" instancję najbardziej konkretnego typu. Pomyślałem, że prawdopodobnie mógłbym to zrobić z lekami generycznymi. Niestety nie udało mi się tego zrobić bez użycia niebezpiecznych operacji. Czy to możliwe?Czy mogę mieć abstrakcyjną klasę konstruktora w języku Java z łańcuchem metod bez wykonywania niebezpiecznych operacji?
Przykładowy kod tego, jak próbuję go (i jak działa) poniżej. Chciałbym uniknąć rzutowania na T w "foo()" (co powoduje niezaznaczone ostrzeżenie), czy można to zrobić?
public class Builders
{
public static void main(final String[] args)
{
new TheBuilder().foo().bar().build();
}
}
abstract class AbstractBuilder<T extends AbstractBuilder<?>>
{
public T foo()
{
// set some property
return (T) this;
}
}
class TheBuilder extends AbstractBuilder<TheBuilder>
{
public TheBuilder bar()
{
// set some other property
return this;
}
public Object build()
{
return new Object();
}
}
Jedną z cech płynnego interfejsu jest to, że istnieje domniemane założenie, że wszystkie metody zwracają "to", gdy prawnie nie muszą - mogą zwrócić zupełnie inny obiekt, o ile ma taki sam zwrot rodzaj. –
Musisz tylko użyć javadoc. Albo w interfejsie, albo w klasie abstrakcyjnej. Użytkownicy klas muszą postępować zgodnie z umową zawartą przez javadoc. Nie ma nic więcej, co możesz zrobić jako projektant aplikacji (więcej, mniej). – mike