Как вернуть ссылку на экземпляр подкласса из суперкласса, когда задействованы параметры типа? - PullRequest
0 голосов
/ 30 апреля 2020

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

class Foo<S, T> {

    <R> Foo<S, R> method(Function<? super T, ? extends R> f) {
         // Implementation ...
    }

}

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

Foo<String, String> obj = new Foo<String, String>()

String result = obj.method(s -> Integer.parseInt(s))
                   .methodTwo(...)
                   .methodThree(...)
                   ...
                   ;

Что я хочу сделать, это превратить Foo в абстрактный класс и иметь два конкретных подкласса, например,

class Bar<S,T> extends Foo<S,T> {
    // Methods exclusive to Bar

    <R> Bar<S, R> barMethod(Function<? super T, ? extends R> f){
        // Implementation...
    }
}

class Baz<S,T> extends Foo<S,T>{
    // Methods exclusive to Baz
}

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

Bar<String, String> obj = new Bar<String, String>()

obj.method(...)   //Should be able to return a Bar<String, Integer> reference automatically
   .barMethod(...)
   .method(...)
   .barMethod(...)
   ...

Я не могу ничего переопределить - если я переопределил - я проиграл. Я пытаюсь найти элегантное решение своей проблемы, но я недостаточно хорошо знаю Java генериков. В идеальном мире я хотел бы сделать что-то вроде этого

abstract class Foo<S, T, I extends Foo> {

    <R> I<S,R> method(Function<? super T, ? extends R> f) {
        // Implementation
        // Some method that will construct an I<S,R>, where I is either Bar or Baz
        //...
    }

}

class Bar<S, T, Bar> extends Foo<S, T, Bar> {
    // Methods exclusive to Bar
}

Конечно, этот синтаксис неправильный и I<S,R> невозможен. Вот где я действительно борюсь - выяснить, как указать тип возвращаемого значения для Foo.method. Я действительно не знаю, возможно ли это в Java, может быть, кто-то знает, как я могу получить эффект, аналогичный тому, что я пытаюсь сделать?

...