简体   繁体   English

在基类中编写一个方法实现,需要在子类中重写?

[英]Write a method implementation in base class which requires override in subclasses?

In Java... 在Java ...

I am creating a class Foo which contains a method doAction(). 我正在创建一个包含方法doAction()的类Foo。 My requirements: 我的要求:

  1. doAction() must have a default implementation (ie function body) in Foo. doAction()必须在Foo中有一个默认实现(即函数体)。
  2. All subclasses of Foo must override doAction(), meaning that subclasses will get a compiler error if they do not provide a new implementation. Foo的所有子类都必须覆盖doAction(),这意味着如果子类不提供新的实现,则会遇到编译器错误。
  3. I need to be able to instantiate Foo. 我需要能够实例化Foo。

abstract would work, except that it does not allow me specify a function body for doAction(). abstract会工作,除了它不允许我为doAction()指定一个函数体。

Edit 编辑

It is impossible to simultaneously satisfy all of the requirements, end of story. 同时满足所有要求,故事结束是不可能的。 You must give up at least one condition, and probably consider an entirely different approach to the problem you're trying to solve. 你必须放弃至少一个条件,并且可能会考虑采用一种完全不同的方法来解决你想要解决的问题。


Use two separate methods. 使用两种不同的方法。 Either: 或者:

abstract class Foo {

    // Override this method
    abstract void doActionInSubclass();

    // You can't override a final method
    // And you don't want subclases to override this one
    final void doAction () {
        // do whatever default-y things you want here
        doActionInSubclass();
    }
}

Or just make the "required" method completely separate from the one you want to force subclasses to override: 或者只是将“required”方法与要强制子类覆盖的方法完全分开:

abstract class Foo {
    abstract void mustOverrideThisInConcreteSubclasses();

    final void doAction() {
        // default-y things here
    }
}

If you give a default implementation to a method in Java, you can't force the subclasses to override it again. 如果为Java中的方法提供默认实现,则不能强制子类再次覆盖它。 If you can, use a template method pattern using a different method name: 如果可以,请使用不同方法名称的模板方法模式:

public class Foo{

    public abstract void templateMethod();
    public final void doAction(){

    //default implementation

     templateMethod(); // call template method
    }
}

Implement your method in Foo and make it always throw an exception, like UnsupportedOperationException . Foo实现您的方法并使其始终抛出异常,如UnsupportedOperationException This will require the subclasses to override the method. 这将要求子类覆盖该方法。

If all subclasses should override it why do you want to provide a default implementation?! 如果所有子类都应该覆盖它,为什么要提供默认实现?! it would be pointless since no one would use it. 因为没有人会使用它,所以毫无意义。 However you probably have some code of your doAction you want to be executed by any subclasses and some code you want to be overridden. 但是,您可能有一些doAction的代码,您希望由任何子类和一些您想要覆盖的代码执行。 In this case you might design as follow: 在这种情况下,您可以设计如下:

doAction(){
     //put your default code here...
     specificAction();
}

abstract specificAction();

In this way doAction has its own implementation which is ended by a specificAction invocation which should instead be implemented by subclasses 这样,doAction就有了自己的实现,它由一个特定的动作调用结束,而这个调用应该由子类实现

In the constructor(s) of class Foo you could use reflection : 在类Foo的构造函数中,您可以使用反射

class Foo {
    public Foo() {
        Class c = getClass();
        if (!c.equals(Foo.class))
        {
            // try/catch omitted for brevity
            Method m = c.getMethod("methodName", new Class[0]);
            if (m.getDeclaringClass().equals(Foo.class))
            {
                throw new Exception("blah blah blah");
            }
        }
    }
}

This won't produce a compile-time error, but since the call to super() in a constructor can't be wrapped with try there's no way for anyone making a subclass to get around it. 这不会产生编译时错误,但由于在构造函数中调用super()不能用try包装,所以任何人都无法创建子类来绕过它。

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

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM