Хвостовая рекурсия происходит через иерархию классов - PullRequest
1 голос
/ 25 октября 2019

Привет вам, люди там,

Я задаю себе следующий вопрос. Это должно быть сделано в Java, но так как я в любом случае не знаю, как это сделать, может помочь и концепция: у меня есть следующий код:

public abstract class A {

   protected enum AType implements AInterface {
     A_VALUE
   }

   public AInterface[] possibleRequests() {
      AInterface types = AType.values();
      return ArrayUtils.concat(types, possibleFurtherRequests());
   }

   public abstract AInterface[] possibleFurtherRequests();

}

public class B extends A {

   protected enum BType implements BInterface {
     B_VALUE
   }

   @Override
   protected AInterface[] possibleFurtherRequests() {
      //Here is my problem.
      return BType.values();
   }
}

public interface AInterface {
}

public interface BInterface extends AInterface {
}

То, что я хочу сделать, это иметь эти possibleRequest -методы в неопределенной глубине. Они должны быть доступны только через A, я не знаю и не должен знать, к какому классу относится объект типа A.

Под неопределенной глубиной я подразумеваю, что эта концепция была расширена с помощьюC extends B. Теперь я хочу получить доступ ко всем значениям из A, B и C. Как сделать так, чтобы всякий раз, когда добавлялся новый подкласс, программист вынужден определять эти AInterface-перечисления (необязательно) и как заставить его реализовать метод, который затем вызывается рекурсивно по иерархии класса (не необязательно),Мне не нужна помощь в определении абстрактного метода или его переопределении. То, что я хочу сделать, это НЕ переопределять существующий и НЕ добавлять абстрактный метод к каждому вызываемому классу наследования.

Честно говоря, я не знаю, как задать этот вопрос, но я надеюсь, что кто-то там понимает, чтоЯ имею в виду. Если нет, оставьте комментарий.

1 Ответ

0 голосов
/ 25 октября 2019

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

protected enum AType implements AInterface {
    A_VALUE
}

protected enum BType implements BInterface {
    B_VALUE
}

public abstract class A {

    final public AInterface[] possibleRequests() {
        return possibleFurtherRequests();
    }

    protected AInterface[] possibleFurtherRequests() {
        return AType.values();
    }

    protected AInterface[] combine(AInterface[] some, AInterface[] more) {
        AInterface[] combined = new AInterface[some.length + more.length];
        System.arraycopy(some, 0, combined, 0, some.length);
        System.arraycopy(more, 0, combined, some.length, more.length);
        return combined;
    }
}

public class B extends A {

    @Override
    protected AInterface[] possibleFurtherRequests() {
        return combine(super.possibleFurtherRequests(), BType.values());
    }
}

public interface AInterface {
}

public interface BInterface extends AInterface {
}

public void test() {
    AInterface[] result = new B().possibleRequests();
    Stream.of(result).forEach(System.out::println);
}

И результат -

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