如何在不使用抽象的情况下强制在子类中实现方法?

2022-09-01 20:45:24

我想强制子类实现我母类的实现方法。我看了这个Java - 强制实现一个实现的方法,但我不能将我的母类转换为抽象类。

public class myMotherClass { 

   myMethod {

      ...some code ..

   }

}

public class myClass extends myMotherClass {

   myMethod {

      ... other code ...
   }

}

因此,在这个示例中,我想强制 myClass 实现 myMethod。

对不起我的英语...


答案 1

不能强制子类重写方法。您只能通过使其抽象来强制它实现方法。

因此,如果您无法使myMotherClass抽象,则只能引入另一个扩展myMotherClass的超类,并将委托给必须实现的方法:

public abstract class EnforceImplementation extends myMotherClass {

        public final void myMethod(){
             implementMyMethod();
        }

        public abstract void implementMyMethod();
}

编辑

我发现了另一种解决问题的中间方法,例如由mojito使用的hemcrest api。

public interface Matcher<T> extends SelfDescribing {

    /**
     * Evaluates the matcher for argument <var>item</var>.
     * <p/>
     * This method matches against Object, instead of the generic type T. This is
     * because the caller of the Matcher does not know at runtime what the type is
     * (because of type erasure with Java generics). It is down to the implementations
     * to check the correct type. 
     *
     * @param item the object against which the matcher is evaluated.
     * @return <code>true</code> if <var>item</var> matches, otherwise <code>false</code>.
     *
     * @see BaseMatcher
     */
    boolean matches(Object item);

    /**
     * This method simply acts a friendly reminder not to implement Matcher directly and
     * instead extend BaseMatcher. It's easy to ignore JavaDoc, but a bit harder to ignore
     * compile errors .
     *
     * @see Matcher for reasons why.
     * @see BaseMatcher
     */
    void _dont_implement_Matcher___instead_extend_BaseMatcher_();
}

接口指定方法 。当然,它不会阻止其他人实现该接口,但它会引导开发人员朝着正确的方向前进。_dont_implement_Matcher___instead_extend_BaseMatcher_Matcher

BaseMatcher 类将该方法实现为 final_dont_implement_Matcher___instead_extend_BaseMatcher_

public final void _dont_implement_Matcher___instead_extend_BaseMatcher_() {
    // See Matcher interface for an explanation of this method.
}

最后,我认为这是一个设计问题,因为模糊地实现了每个匹配器应该实现的逻辑。因此,最好使 Matcher 成为抽象类并使用模板方法。BaseMatcher

但我想他们这样做是因为这是字节码兼容性和新功能之间的最佳折衷方案。


答案 2

您可以重新设计层次结构,以便您的具体类只是树的叶子。

而不是

myClass extends myMotherClass

考虑

myClass extends myMotherAbstractClass
myMotherClass extends myMotherAbstractClass 

这样,抽象类将由两个实例化类继承。在这种情况下,可能会非常薄,只是实现。myMotherClassmyMethod