Может ли абстрактный суперкласс проверять экземпляр самого себя (для определения подкласса) во время выполнения? - PullRequest
1 голос
/ 11 марта 2020

Допустим, у меня есть этот фрагмент кода:

public abstract class InferenceRule {

    protected abstract void provability(Line line) throws InferenceException;

    public void checkProvability(Line line) throws InferenceException {
        // ??
    }

}

Существуют уникальные подклассы для различных типов InferenceRule. Они бы реализовали абстрактный метод #provability(Line). Каждый объект строки содержит InferenceRule.

public class Line {

    private InferenceRule inferenceRule;

    public InferenceRule getInferenceRule() {
        return inferenceRule;
    }

}

Я хочу закодировать его так, чтобы для метода InferenceRule#checkProvability(Line) можно было проверить правило вывода строки и посмотреть, является ли это правило тем же экземпляром (или подклассом) это правило вывода. Т.е.

line.getInferenceRule() instanceof this

Но это всегда будет возвращать true, потому что InferenceRule#checkProvability(Line) находится в абстрактном суперклассе, а все подклассы InferenceRule, по необходимости, являются экземплярами суперкласса InferenceRule. Итак, есть ли способ для суперкласса определить, к какому подклассу он сам относится (во время выполнения)? таким образом, я мог бы проверить, является ли подкласс этого объекта тем же экземпляром правила вывода, который содержится в строке.

Вот несколько примеров реализаций класса InferenceRule: 1. Окончательный, неабстрактный подкласс класса

public final class AssumptionIR extends InferenceRule {

    @Override
    protected void provability(Line line) throws InferenceException {
        // implementation
    }

    // other methods unique to this class
}
Абстрактный подкласс
public abstract class DischargeIR extends InferenceRule {
    // other methods unique to this class
}
Анонимный класс, который может расширять сам DischargeIR или InferenceRule.
public static final InferenceRule IR_MODUS_POLLENS = new InferenceRule() {
        @Override
        protected void provability(Line line) throws InferenceException {
            // implementation
        }
    };

public static final DischargeIR IR_IF_INTRO = new DischargeIR() {
        @Override
        protected void provability(Line line) throws InferenceException {
            // implementation
        }
    };

Каждый анонимный класс должен быть только тем же экземпляром, что и он сам (в этом случае IR_IF_INTRO должен быть тем же экземпляром, что и DischargeIR, тогда как IR_IF_INTRO не должен совпадать с IR_MODUS_POLLENS), а не его абстрактный суперкласс. Каждый неабстрактный подкласс (AssumpIR) не должен быть одним и тем же экземпляром своего суперкласса.

1 Ответ

3 голосов
/ 11 марта 2020

Этого можно добиться, используя Class#isAssignableFrom():

public void checkProvability(Line line) throws InferenceException {
    if(getClass().isAssignableFrom(line.getInferenceRule().getClass())) {
        // ...
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...