简体   繁体   English

如何强制子类调用抽象实现的方法

[英]How to force subclass to call an abstract implemented method

Basically, what I want to do is force the subclass to call an abstract superclass method (implemented in the subclass), so I don't have to explicitly write it each time I create a new subclass.基本上,我要做的就是强制子类调用一个抽象超类方法(在子类中实现),这样就不用每次新建子类的时候都显式地写了。

I wrote it in the superclass' constructor once, because I want it to force it for every implementation.我在超类的构造函数中写过一次,因为我希望它为每个实现强制它。

public abstract class SupahClass {
    public SupahClass() {
        doStuff(); // It IS executed when the subclass constructor is called
        init(); // NOT executed, even though it's implemented
    }

    private void doStuff() { ... }        

    protected abstract void init();
}

public class SomeSubClass extends SupahClass {

    // The problem lies HERE: this is executed AFTER init() ... so it gets NULL again
    private TextBox myTextBox = null;

    public SomeSubClass() {
        super(); // invokes the super constructor, so init() should be called
        // I could call init(); here EACH time i create a new subclass... but no :)
    }

    @Override
    public void init() {
        this.myTextBox = new TextBox(); // Executed BEFORE its declared as null above
    }
}

Of course, the superclass can't really call it since its an abstract (so undefined) method, but its an ABSTRACT class so it cannot be instanciated, it must delegate the task to its subclasses, so why cant they call the abstract but now implemented method?当然,超类不能真正调用它,因为它是一个抽象(未定义)方法,但它是一个 ABSTRACT class 所以它不能被实例化,它必须将任务委托给它的子类,所以为什么他们不能调用抽象但现在实现方法?

EDIT See the subclass property myTextBox and the init() implementation编辑查看子类属性myTextBoxinit()实现

Which approach do you think I should do?你认为我应该采取哪种方法? Remove the = null in the property declaration (duhhh)删除属性声明中的= null (duhhh)

or remove the init() in the superclass and explicitly calling it in the subclass constructor (this is what I wanted to avoid, since I will have to write it 100% of the time..)或删除超类中的init()并在子类构造函数中显式调用它(这是我想避免的,因为我必须 100% 的时间编写它..)

I can't reproduce this.我无法重现这个。 init() will be called, assuming no exceptions are thrown first. init()被调用,假设没有首先抛出异常。 Short but complete example:简短但完整的示例:

abstract class Superclass {
   public Superclass() {
       init();
   }

   protected abstract void init();
}

class Subclass extends Superclass {
   public Subclass() {
       super();
   }

   @Override
   public void init() {
       System.out.println("Subclass.init called");
   }
}

public class Test {    
    public static void main(String[] args) throws Exception {
        new Subclass();
    }
}

That prints "Subclass.init called" as expected.按预期打印“Subclass.init called”。 I suspect something else is wrong in code that you haven't shown us.我怀疑您没有向我们展示的代码中还有其他问题。

Note that calling virtual methods in a constructor is a risky business - the subclass won't have been initialized yet - all the variables will have their default values, for example.请注意,在构造函数中调用虚方法是有风险的——例如,子类还没有被初始化——所有的变量都会有它们的默认值。 It's generally a pattern to be avoided.这通常是一种要避免的模式。

Abstract classes can call abstract methods.抽象类可以调用抽象方法。

You can fix this by changing your declaration to:您可以通过将声明更改为:

private TextBox myTextBox;

The assignment to null serves no useful purpose.分配给 null 没有任何用处。 If there was no superclass, it would do nothing, because fields are initialised to null anyway.如果没有超类,它什么也不做,因为无论如何字段都初始化为 null。 Since there is a superclass, it acts as a gunshot to the foot.由于有一个超类,它就像对脚的枪击一样。 So, get rid of it.所以,摆脱它。

Have you used a debugger to understand what the code is doing?您是否使用调试器来了解代码在做什么?

The order of construction is 1. constructor of base class 2. initialize all members of derived class 3. constructor of derived class.构造顺序为 1. 基类 class 的构造函数 2. 初始化派生 class 的所有成员 3. 派生 class 的构造函数。

In your case step 1 initializes the member (in init of the derived class - called via polymorphic call) but step 2 sets it to null.在您的情况下,步骤 1 初始化成员(在派生的 class 的 init 中 - 通过多态调用调用),但步骤 2 将其设置为 null。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 如何在不使用抽象的情况下强制实现子类中的方法? - How to force implementation of a method in subclass without using abstract? 是否有一种设计模式可以强制初始化子类实现的方法? - Is there a design pattern to force initialization of a subclass implemented method? 强制子类实现抽象子类 - Force a subclass to implement abstract subclass 如何调用子类的方法? - How to call method of the subclass? 确保在每次调用 B(抽象实现方法)之后调用方法 A? - Ensure method A is called after every call of B (an abstract implemented method)? 如何在Eclipse中查找抽象方法的实现位置? - How to find where an abstract method is implemented in Eclipse? 抽象类如何访问子类的方法? - How does the abstract class access the method of the subclass? 克隆已实现的抽象方法 - Cloning an implemented abstract method 如何在不实例化任何子类的情况下调用在子类之间通用的抽象类方法 - How could I call an abstract class method who is common between subclasses without instanciating any subclass 在Android AppCompatActivity中,每个扩展BaseActivity的子类都可以实现一种抽象方法吗? - In Android AppCompatActivity, can I have an abstract method being implemented by each subclass that extends BaseActivity?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM