Java Обобщения, возвращаемый тип для доступа только к защищенным методам абстрактного типа - PullRequest
0 голосов
/ 06 апреля 2020

У меня есть следующие настройки в моем приложении

//Package 1
public class class1 extends AbstractClass2<class1>{

  public void someMethod(){
    // What i want here is when i call the method "with", I should be able to chain only 
    // the methods defined in AbstractClass3 and not the methods defined in its sub classes.
    with(10).someOtherMethod() // this should be possible (it is possible with the current setup)
    with(10).someMethod() // this should not be possible (it is possible with the current setup)
  }

}

//Package 2
public abstract class AbstractClass2<T> extends AbstractClass3<T>{
  protected void someMethod(){
  }
}

public abstract class AbstractClass3<T>{

  protected T with(int value){
    setValue(value);
    return (T) this;
  }

  protected void someOtherMethod(){
  }

}

В основном то, что я пытаюсь добиться цепочки методов, но ограничить это методами, определенными в базовом классе "AbstractClass3". Как мне этого добиться?

1 Ответ

0 голосов
/ 07 апреля 2020

Проблема в with(int value) и someOtherMethod(). И вам также не нужны генерики в AbstractClass3 (по крайней мере, в приведенном вами примере).

Ваш метод "with" должен быть protected AbstractClass3 with(int value). Обратите внимание, что метод теперь возвращает AbstractClass3, что означает, что будут доступны только методы, определенные в этом классе (если вы не приведете его к подклассу).

Наконец, в броском трюке метод видимости someOtherMethod(), который должен быть опубликован c. Если вы находитесь в другом пакете, вы можете вызывать защищенные методы только по ссылке this. (по наследству, конечно).

Я думаю, это лучше объяснить в коде с комментариями:

public abstract class AbstractClass3 {

    protected AbstractClass3 with(int value) {
        // Do stuff.
        return this;
    }

    // If "someOtherMethod()" is protected, you will only be able to call
    // it from sub-classes using "this." reference if you are in a different package.
    // So, we make it public.
    public void someOtherMethod() {
    }

}

public abstract class AbstractClass2<T> extends AbstractClass3 {
    protected void someMethod() {
    }
}

public class Class1 extends AbstractClass2<ANY_CLASS_HERE> {

    public void someMethod() {
        // If someOtherMethod() is protected, this will NOT work because you are not calling it
        // through "this." reference. YOU CAN ONLY CALL PROTECTED METHODS THROUGH "this." reference
        // IF YOU ARE IN A DIFFERENT PACKAGE. As you are calling someOtherMethod() from another 
        // instance returned by "with(10)", that means that you are calling it "outside"; 
        // the "this." reference is "inside" the instance returned by "with(10)". In order for 
        // it to work, someOtherMethod() must be public (or be in the same package).
        // Remember: You need "this." reference to call protected methods in different packages.
        with(10).someOtherMethod();

        // If someOtherMethod() is protected, this works because you are calling
        // it through "this." reference. It's a straight call to the parent.
        this.someOtherMethod(); // Note the "this." reference.

        // ERROR because someMethod() does not exists in AbstractClass3 and "with(10)".
        // returns an AbstractClass3 instance.
        with(10).someMethod();
    }

}

Я взял дженерики из AbstractClass3, но вы можете вернуть их в любое время. Здесь важно понимать, что ваш метод with должен возвращать AbstractClass3, а защищенные методы можно вызывать только по ссылке this., если вы находитесь в другом пакете.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...