【问题标题】:Can an abstract superclass check the instance of itself (to determine the subclass) at runtime?抽象超类可以在运行时检查自身的实例(以确定子类)吗?
【发布时间】:2020-03-11 20:40:05
【问题描述】:

假设我有这段代码:

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 的实例。那么,有没有办法让超类确定它本身是哪个子类的实例(在运行时)?这样,我可以检查该对象的子类是否与 Line 所包含的推理规则的实例相同。

以下是 InferenceRule 类的一些实现示例: 1.最终的、非抽象的子类类

public final class AssumptionIR extends InferenceRule {

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

    // other methods unique to this class
}
  1. 抽象子类
public abstract class DischargeIR extends InferenceRule {
    // other methods unique to this class
}
  1. 可以扩展 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) 不应是其超类的同一个实例。

【问题讨论】:

  • 是的,您可以按照自己的方式进行操作,但这不是一个非常适合 OOP 的解决方案。我建议您更多地了解多态性以及如何利用它来做您想做的事。例如,您可以在超类中调用provability(),它会根据当前对象的类型在子类中调用正确的版本。或者您可以在每个子类中覆盖checkProvability()
  • “不同类型的 InferenceRule 有独特的子类。它们将实现抽象方法 #provability(Line)。”请显示一个示例子类,就像您在此处用文字描述的那样。这将有助于我们提供更具体的建议。请参阅minimal reproducible example,了解有关如何创建好的代码示例的提示。
  • @Code-Apprentice 我已经更新了这个问题。所以我有一个抽象超类InferenceRule,它扩展了3个类:PremiseIRAssumpIRDischargeIR。这 3 个对象都有它们独有的方法或字段。 PremiseIRAssumpIR 是最终的非抽象类,而 DischargeIR 是抽象的。用户旨在扩展(或创建匿名类)DischargeIRInferenceRule 本身,具体取决于它的推理规则。用户还需要创建PremiseIRAssumpIR 的实例,而无需接触其代码。
  • 允许用户直接实现InferenceRule 的一个原因是,不是PremiseIRAssumpIRDischargeIR 的对象将没有任何不存在的唯一方法InferenceRule。如果我要创建另一个类,以便用户在与DischargeIR 相同的级别实现它,则该类将为空。

标签: java inheritance


【解决方案1】:

您可以使用Class#isAssignableFrom()

public void checkProvability(Line line) throws InferenceException {
    if(getClass().isAssignableFrom(line.getInferenceRule().getClass())) {
        // ...
    }
}

【讨论】:

  • 哦!我认为getClass() 返回超类。谢谢!
  • 好的,尝试打印getClass().getName()line.getInferenceRule().getClass().getName()来调试问题。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-04-04
  • 2015-10-07
  • 2021-08-02
  • 2020-11-21
相关资源
最近更新 更多