有没有办法让一个方法不是抽象的但必须被覆盖?

53 java inheritance abstract-class overriding abstract-methods

有没有办法强制子类覆盖超类的非抽象方法?

我需要能够创建父类的实例,但是如果一个类扩展了这个类,它必须给出它自己的一些方法的定义.

Joa*_*uer 37

据我所知,没有直接编译器强制执行的方法.

您可以通过使父类可实例化来解决它,而是提供一个工厂方法来创建具有默认实现的某个(可能的私有)子类的实例:

public abstract class Base {
  public static Base create() {
    return new DefaultBase();
  }

  public abstract void frobnicate();

  static class DefaultBase extends Base {
    public void frobnicate() {
      // default frobnication implementation
    }
  }
}
Run Code Online (Sandbox Code Playgroud)

你现在不能new Base(),但你可以做到Base.create()默认实现.

  • 我觉得需要指出一个子类无法通过调用`super.frobincate()`来获取父类的默认实现,因为子类将继承`Base`而不是`DefaultBase`.否则,我认为这是一个很棒的解决方法. (8认同)

Dan*_*den 24

正如其他人所指出的那样,你不能直接这样做.

但一种方法是使用策略模式,如下所示:

public class Base {
    private final Strategy impl;

    // Public factory method uses DefaultStrategy
    // You could also use a public constructor here, but then subclasses would
    // be able to use that public constructor instead of the protected one
    public static Base newInstance() {
        return new Base(new DefaultStrategy());
    }

    // Subclasses must provide a Strategy implementation
    protected Base(Strategy impl) {
        this.impl = impl;
    }

    // Method is final: subclasses can "override" by providing a different
    // implementation of the Strategy interface
    public final void foo() {
        impl.foo();
    }

    // A subclass must provide an object that implements this interface
    public interface Strategy {
        void foo();
    }

    // This implementation is private, so subclasses cannot access it
    // It could also be made protected if you prefer
    private static DefaultStrategy implements Strategy {
        @Override
        public void foo() {
            // Default foo() implementation goes here
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

  • 做得很好.这可能是解决此问题的最优雅方式. (2认同)
  • 这是更好的方法,因为覆盖具有定义的方法是不好的设计.所有方法都应该是final,abstract或empty. (2认同)

Iva*_*tin 6

考虑使用此方法创建一个接口.类后代必须实现它.

  • 基类不需要实现它.请求您需要使用派生对象的接口实例,而不是基类实例.这将强制派生类具有接口实现.您也可以在方法体中检查基类类型. (2认同)

s10*_*6mo 5

我认为最简单的方法是创建一个继承自基类的抽象类:


public class Base {
    public void foo() {
        // original method
    }
}

abstract class BaseToInheritFrom extends Base {
    @Override
    public abstract void foo();
}

class RealBaseImpl extends BaseToInheritFrom {
    @Override
    public void foo() {
        // real impl
    }
}
Run Code Online (Sandbox Code Playgroud)